Фильтровать массив объектов, если объект содержит атрибут со значением, присутствующим в другом массиве - PullRequest
4 голосов
/ 11 марта 2020

У меня есть следующий массив объектов.

const abc = [
      {
        sku: 1,
        features: ["Slim"],
        fields: [
          { label: "Material", value: "Material1" },
          { label: "Type", value: "Type1" },
        ]
      },
      {
        sku: 2,
        features: ["Cotton"],
        fields: [
          { label: "Material", value: "Material2" },
          { label: "Type", value: "Type1" },
        ]
      },
      {
        sku: 3,
        features: ["Cotton"],
        fields: [
          { label: "Material", value: "Material3" },
          { label: "Type", value: "Type2" },
        ]
      }
    ];

Я хочу отфильтровать только те объекты, значения функций и полей которых присутствуют в этом

const fieldsArr = ["Material1", "Material2", "Type1", "Slim"]

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

let output = [
      {
        sku: 1,
        features: ["Slim"],
        fields: [
          { label: "Material", value: "Material1" },
          { label: "Type", value: "Type1" },
        ]
      },
      {
        sku: 2,
        features: ["Cotton"],
        fields: [
          { label: "Material", value: "Material2" },
          { label: "Type", value: "Type1" },
        ]
      },
    ]

Я решил часть функций следующим образом

abc.forEach(e => {
      if (e.features.some(v => fieldsArr.indexOf(v) !== -1)) {
        output.push(e);
      }
    });

Но у меня проблема с фильтрацией части полей. Есть ли способ оптимизировать фильтрацию объектов на основе вышеуказанного условия.

Ответы [ 2 ]

6 голосов
/ 11 марта 2020

Вам нужно итерировать и вложенные массивы.

const
    abc = [{ sku: 1, features: ["Slim"], fields: [{ label: "Material", value: "Material1" }, { label: "Type", value: "Type1" }] }, { sku: 2, features: ["Cotton"], fields: [{ label: "Material", value: "Material2" }, { label: "Type", value: "Type1" }] }, { sku: 3, features: ["Cotton"], fields: [{ label: "Material", value: "Material3" }, { label: "Type", value: "Type2" }] }],        fieldsArr = ["Material1", "Material2", "Type1", "Slim"],
    result = abc.filter(({ features, fields }) =>
        features.some(v => fieldsArr.includes(v)) ||
        fields.some(({ value }) => fieldsArr.includes(value))
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
2 голосов
/ 11 марта 2020

Используйте фильтр и проверьте каждый элемент, объединенный значения features и fields (значение) с поля Arr.

const abc = [
  {
    sku: 1,
    features: ["Slim"],
    fields: [
      { label: "Material", value: "Material1" },
      { label: "Type", value: "Type1" }
    ]
  },
  {
    sku: 2,
    features: ["Cotton"],
    fields: [
      { label: "Material", value: "Material2" },
      { label: "Type", value: "Type1" }
    ]
  },
  {
    sku: 3,
    features: ["Cotton"],
    fields: [
      { label: "Material", value: "Material3" },
      { label: "Type", value: "Type2" }
    ]
  }
];

const fieldsArr = ["Material1", "Material2", "Type1", "Slim"];

const res = abc.filter(item =>
  [...item.features, ...item.fields.map(x => x.value)].some(fea =>
    fieldsArr.includes(fea)
  )
);

console.log(res);

// Update: more concise using destructure
const res2 = abc.filter(({features, fields}) =>
  [...features, ...fields.map(({value}) => value)].some(fea =>
    fieldsArr.includes(fea)
  )
);
console.log(res2);
...