1

Given I have this array of objects:

    let array1 = [
        {id: 1, name: "Test Item 1", price: 100, type: 'item'},
        {id: 1, name: "Test Fee 1", price: 200, type: 'fee'},
        {id: 3, name: "Test 3", price: 300, type: 'item'},
    ]

Now i want to filter so I only have the objects where every key value of the following array match:

    let array2 = [
        {id: 1, type: "item"},
        {id: 3, type: "item"},
    ]

This should return array1[0] and array1[2]. My current solution has been this, but it wont work if array2 has multiple object keys to compare to:

array1.filter(row => {
    return array2.find(r => {
        return Object.entries(row).some(([key, value]) => r[key] === value);
    })
});
5
  • Does this answer your question? Comparing two arrays of objects, and exclude the elements who match values into new array in JS Commented Oct 21, 2022 at 14:39
  • Not really, as that does the inverse and it also filters by a hardcoded key (id), i need to filter by comparing to multiple key/value pairs. Commented Oct 21, 2022 at 14:40
  • @GrafiCode array1 should only return objects where each key/value of one of the objects in array2 match. So not only type is taken into consideration, but also id. (note theres two times the same id on array1 with a different type). I'm just bad at explaining :) Commented Oct 21, 2022 at 14:46
  • Do it the other way round: Object.entries(r).every(([key, value]) => row[key] === value). Get the entries of r and check if every value in second array is present in the row object Commented Oct 21, 2022 at 14:47
  • @adiga You're a hero. Such a simple solution after all. Works flawlessly, thanks! If you post it as an answer, I'll be glad to mark it as the accepted one. Commented Oct 21, 2022 at 14:52

3 Answers 3

2
array1.filter((row) =>
  array2.some((template) =>
    Object.keys(template).every((key) => template[key] === row[key])
  )
);

I think the answer in comment above is cleaner than mine.

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

Comments

1

In array1.filter() you can iterate all objects in array2 and compare keys using Object.keys()

let array1 = [
  {id: 1, name: "Test Item 1", price: 100, type: 'item'},
  {id: 1, name: "Test Fee 1", price: 200, type: 'fee'},
  {id: 3, name: "Test 3", price: 300, type: 'item'},
]

 let array2 = [
   {id: 1, type: "item"},
   {id: 3, type: "item"},
 ]

const res = array1.filter(row => {
  for (const obj of array2) {
    if (Object.keys(obj).every(k => obj[k] === row[k])) {
      return row
    }
  }
})

console.log(res)

Comments

1

Lodash if you don't mind:

const array1 = [{id: 1, name: "Test Item 1", price: 100, type: 'item'},{id: 1, name: "Test Fee 1", price: 200, type: 'fee'},{id: 3, name: "Test 3", price: 300, type: 'item'}];
const array2 = [{id: 1, type: "item"},{id: 3, type: "item"}];

const fn = _.overSome(array2.map(_.matches));
const result = _.filter(array1, fn);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0 }
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>

Comments

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.