基于不同的对象对多级对象应用过滤器

Apply a filter on a multilevel object based on a different object

我有一个包含多级对象的数组,例如:

list= [ {  
           type: { name: 'dog', size:'medium'},
           entity: { name: 'Tobby',  age: '7'},
         },
         {  
           type: { name: 'cat', size:'small'},
           entity: { name: 'Garfield',  age: '7'},
         }
    ]

我有一个定义的过滤器,例如:

filter={
         type: { name:'dog'}}

我需要定义一个可以调用的函数

let filtered = list.thisMagicFilter(filter)

这将在我的列表中进行相应的过滤(在给定的示例中,仅返回第一个元素。

逻辑上,如果过滤器是 {entity:{age:'7'}},则应返回两个结果。

我在使用 list.filter() 的函数式编程中试图做到这一点时我已经崩溃了,但它对我来说太复杂了:我正在为它是一个 2 级验证这一事实而苦苦挣扎。

我能得到一些关于如何解决这个问题的提示吗?

提前致谢!

试试这个:

const _matchesFilter = (e, conditions = []) =>
  conditions.every(([prop, condition]) => {
    const subConditions = Object.entries(condition);
    return subConditions.every(([ subProp, subCondition ]) =>
      e[prop]?.[subProp] === subCondition
    );
  });

const thisMagicFilter = (list = [], filter = {}) => {
  const conditions = Object.entries(filter);
  return list.filter(e => _matchesFilter(e, conditions));
}

const list= [ 
  { type: { name: 'dog', size:'medium'}, entity: { name: 'Tobby',  age: '7'} },
  { type: { name: 'cat', size:'small'}, entity: { name: 'Garfield',  age: '7'} }
];
console.log( thisMagicFilter(list) );
console.log( thisMagicFilter(list, { type: { name: 'dog'} }) );
console.log( thisMagicFilter(list, { entity: { age: '7'} }) );
console.log( thisMagicFilter(list, { entity: { name: 'Garfield', age: '7'} }) );
console.log( thisMagicFilter(list, { type: { size: 'medium' }, entity: { age: '7'} }) );

您可以对嵌套对象进行递归筛选,并移交零件文件管理器和零件数据对象,直到不再有嵌套对象。

const
    list = [{ type: { name: 'dog', size: 'medium' }, entity: { name: 'Tobby', age: '7' } }, { type: { name: 'cat', size: 'small' }, entity: { name: 'Garfield', age: '7' } }],
    filter = { type: { name: 'dog' } },
    filterBy = f => o => Object
        .entries(f)
        .every(([k, v]) => typeof v === 'object'
            ? filterBy(v)(o[k])
            : o[k] === v
        ),
    result = list.filter(filterBy(filter));

console.log(result);   
.as-console-wrapper { max-height: 100% !important; top: 0; }