#javascript #filter #functional-programming
Вопрос:
У меня есть массив с многоуровневыми объектами, такими как:
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'}}
, то должны быть возвращены оба результата.
Я сломал голову , пытаясь сделать это в функциональном программировании с помощью a list.filter()
, но это просто слишком сложно для меня: я борюсь с тем фактом, что это проверка на 2 уровне.
Могу ли я получить некоторые подсказки о том, как решить эту проблему?
Заранее благодарю вас!
Ответ №1:
Вы можете использовать рекурсивный фильтр для вложенных объектов и передавать файл детали и объект данных детали до тех пор, пока вложенные объекты не исчезнут.
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 =gt; o =gt; Object .entries(f) .every(([k, v]) =gt; 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; }
Ответ №2:
Попробуй это:
const _matchesFilter = (e, conditions = []) =gt; conditions.every(([prop, condition]) =gt; { const subConditions = Object.entries(condition); return subConditions.every(([ subProp, subCondition ]) =gt; e[prop]?.[subProp] === subCondition ); }); const thisMagicFilter = (list = [], filter = {}) =gt; { const conditions = Object.entries(filter); return list.filter(e =gt; _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'} }) );