0

Sample code.

const cards = [
    {
        id: "1",
        name: "J",
        tag: [
          {
            "colour": "red"
          },
          {
            "colour": "yello"
          },
          {
            "colour": "blue"
          },
          {
            "colour": "white"
          },
        ],
        size: [
          {
            "name": "small"
          },
          {
            "name": "medium"
          },
        ],
    },
    {
        id: "2",
        name: "S",
        tag: [
          {
            "colour": "red"
          },
          {
            "colour": "green"
          },
          {
            "colour": "black"
          },
        ],
        size: [
          {
            "name": "small"
          },
          {
            "name": "medium"
          },
        ],
    },
    {
        id: "3",
        name: "K",
        tag: [
          {
            "colour": "green"
          },
          {
            "colour": "purple"
          },
          {
            "colour": "brown"
          },
          {
            "colour": "white"
          },
        ],
        size: [
          {
            "name": "large"
          },
        ],
    }
];

Test arrays

const sizeArray = ["medium", "small"];
const tagArray = ["red", "black"];

I want the filtered array of objects to only include the second object in this example. Filtering only those who match all criteria leaving me with a new array of objects.

I've tried with .filter, .some, .includes and no luck looking over many other answers to similar questions.

Thanks a lot.

1
  • can you describe what you want and what the desired outcome looks like? Commented Jun 4, 2021 at 1:37

2 Answers 2

3

You can use the filter with every and some.

Since you need to filter the result which contains all sizeArray and tagArray in size and tag array respectively.

const cards = [
  {
    id: "1",
    name: "J",
    tag: [
      {
        colour: "red",
      },
      {
        colour: "yello",
      },
      {
        colour: "blue",
      },
      {
        colour: "white",
      },
    ],
    size: [
      {
        name: "small",
      },
      {
        name: "medium",
      },
    ],
  },
  {
    id: "2",
    name: "S",
    tag: [
      {
        colour: "red",
      },
      {
        colour: "green",
      },
      {
        colour: "black",
      },
    ],
    size: [
      {
        name: "small",
      },
      {
        name: "medium",
      },
    ],
  },
  {
    id: "3",
    name: "K",
    tag: [
      {
        colour: "green",
      },
      {
        colour: "purple",
      },
      {
        colour: "brown",
      },
      {
        colour: "white",
      },
    ],
    size: [
      {
        name: "large",
      },
    ],
  },
];

const sizeArray = ["medium", "small"];
const tagArray = ["red", "black"];

const result = cards.filter(({ tag, size }) =>
    sizeArray.every((s) => size.some((si) => si.name === s)) &&
    tagArray.every((t) => tag.some((ta) => ta.colour === t))
);

console.log(result);

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

1 Comment

Done. Thanks again, I appreciate your help.
2

As you filter the main array, you want to make sure at least one of the tag values is in the tagArray and at least one of the size values is in the sizeArray. This can be achieved using includes.

const cards=[{id:"1",name:"J",tag:[{colour:"red"},{colour:"yello"},{colour:"blue"},{colour:"white"}],size:[{name:"small"},{name:"medium"}]},{id:"2",name:"S",tag:[{colour:"red"},{colour:"green"},{colour:"black"}],size:[{name:"small"},{name:"medium"}]},{id:"3",name:"K",tag:[{colour:"green"},{colour:"purple"},{colour:"brown"},{colour:"white"}],size:[{name:"large"}]}];

const sizeArray = ["medium", "small"];
const tagArray = ["red", "black"];

const filtered = cards.filter((card) => {
  return (
    card.tag.some((tag) => tagArray.includes(tag.colour)) &&
    card.size.some((size) => sizeArray.includes(size.name))
  );
});

console.log(filtered);

Note that includes isn't super efficient, but I'm assuming you're not working with tons of data here. If your sizeArray or tagArray are especially large, you could look into something like the Set object for hash table efficiency.

3 Comments

Needs to be tagArray.every && sizeArray.every in order to only return second object as op expects
Sure it would if you test the filter arrays that every value is found in the object. See answer below using that approch
Thank you, Nick, that was helpful. I did need it to return only the objects that matched as Charlie commented. I will take your advice on the hash table efficiency as the DB dataset will likely be large. Thanks again.

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.