4

I have the following array of objects.

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" },
        ]
      }
    ];

I want to filter only those objects whose features and fields value are present in this

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

Expected Output is

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" },
        ]
      },
    ]

I solved the features part like this

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

But I'm having problem with filtering the fields part. Is there a way to filter the objects based on the above condition in an optimized way.

1
  • Why do you use forEach and push when you can use filter? Commented Mar 11, 2020 at 9:54

2 Answers 2

7

You need to iterate the nested arrays as well.

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; }

Sign up to request clarification or add additional context in comments.

Comments

2

Use filter, and check each items combined values of features and fields (value) with fieldsArr.

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);

1 Comment

np! @YogeshKudikala, Check out now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.