Фильтровать массив объектов на основе критериев в другом массиве объектов - PullRequest
0 голосов
/ 01 ноября 2018

Я хочу отфильтровать элементы из массива categories на основе критериев в массиве otherCategories.

Если otherCategories содержит объект, где title соответствует одному заголовку из categories.subCategory[i].title, а name соответствует categories.subCategory[i].details.name, то отфильтруйте только этот объект, например, "item1" из categories.

var categories = [
{
    title:"item1",
    subCategory:[
        {
            title:"subCat1",
            details:{
                name:"detail1",
                email:"test@test.com"
            }
        },
        {
            title:"subCat2",
            details:{
                name:"detail2",
                email:"test@test.com"
            }
        }
    ]
},
{
    title:"item2",
    subCategory:[
        {
            title:"subCat1",
            details:{
                name:"detail3",
                email:"test@test.com"
            }
        },
        {
            title:"subCat2",
            details:{
                name:"detail2",
                email:"test@test.com"
            }
        }
    ]
}
]

var otherCategories = [
{
    title:"subCat1",
    name:"detail1"        
}
]

Ожидаемый результат

categories = [
{
    title:"item1",
    subCategory:[
        {
            title:"subCat1",
            details:{
                name:"detail1",
                email:"test@test.com"
            }
        },
        {
            title:"subCat2",
            details:{
                name:"detail2",
                email:"test@test.com"
            }
        }
    ]
}]

Ответы [ 3 ]

0 голосов
/ 01 ноября 2018

Другой подход, который обычно работает для простых объектов, таких как в вашем примере, заключается в преобразовании массива otherCategories в массив «строковых» объектов, а затем фильтрации categories путем сравнения «строковых» версий желаемые пары ключей subCategory значения для преобразованного массива otherCategories.

Важно отметить, однако, что порядок свойств объекта не гарантируется в JavaScript (хотя многие браузеры сохраняют порядок свойств). Это означает, что этот подход может не работать в некоторых ситуациях, и подход, подобный предложенному @ NikhilAggarwal , более стабилен.

Например:

const categories = [{title: "item1", subCategory: [{title: "subCat1", details: {name: "detail1", email: "test@test.com"}},{title: "subCat2", details: {name: "detail2", email: "test@test.com"}}]}, {title: "item2", subCategory: [{title: "subCat1", details: {name: "detail3", email: "test@test.com"}},{title: "subCat2", details: {name: "detail2", email: "test@test.com"}}]}];
const otherCategories = [{title: "subCat1", name: "detail1"}];

let matches = otherCategories.map((item) => JSON.stringify(item));
let results = categories.filter((item) => {
  for (let sub of item.subCategory) {
    let match = JSON.stringify({title: sub.title, name: sub.details.name});
    if (matches.includes(match)) {
      return item;
    }
  }
});
console.log(results);
0 голосов
/ 01 ноября 2018

Вы можете map категории результатов filtering подкатегории:

  function matches(sub, filters) {
    return filters.some(filter => filter.title === sub.title && filter.name === sub.name);
 }

 const result = categories.map(({ title, subCategories }) => ({ title, subCategories: subCategories.filter(sub => matches(sub, otherCategories)) }));
0 голосов
/ 01 ноября 2018

Использование Array.reduce , Array.filter & Array.some

  • Преобразовать массив otherCategories в объект с заголовком в качестве ключа и именем в качестве значения
  • Фильтр categories массив, где существует subCategory с соответствующими значениями

var categories = [{title:"item1",subCategory:[{title:"subCat1",details:{name:"detail1",email:"test@test.com"}},{title:"subCat2",details:{name:"detail2",email:"test@test.com"}}]},{title:"item2",subCategory:[{title:"subCat1",details:{name:"detail3",email:"test@test.com"}},{title:"subCat2",details:{name:"detail2",email:"test@test.com"}}]}];
var otherCategories = [{title:"subCat1",name:"detail1"}];
var obj = otherCategories.reduce((a,c) => Object.assign(a,{[c.title]:c.name}), {});

categories = categories.filter(v => v.subCategory.some(o => obj[o.title] === o.details.name));
console.log(categories);
...