基于不同的对象对多级对象应用过滤器
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; }
我有一个包含多级对象的数组,例如:
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; }