Mikel Granero
Mikel Granero

Reputation: 419

How to efficiently find the objects of one array in another array?

Let's say I have an array with some objects:

var objectsToFind = [
  {
    name: 'first',
    value: 1,
  },
  {
    name: 'second',
    value: 2,
  },
  {
    name: 'third',
    value: 3,
  }
];

And I want to get the objects of this array that match the name property of the previous array's objects:

var findHere = [
  {
    name: 'fourth',
    size: 36,
  },
  {
    name: 'second',
    size: 689,
  },
  {
    name: 'third',
    size: 47,
  },
  {
    name: 'sixth',
    size: 34,
  },
];

So the result would be:

var result = [
  {
    name: 'second',
    size: 689,
  },
  {
    name: 'third',
    size: 47,
  },
];

I made a method that returns the objects using foreach and a find method, but I don't know if this is the most efficent way. Is there a better way to achieve this?

My code to achieve this:

      var foundObjects = [];
      objectsToFind.forEach(object => {
        const found = findHere.find(element => element.name == object.name);
        if (found != null) {
          foundObjects.push(found);
        }
      });

Upvotes: 0

Views: 115

Answers (1)

georg
georg

Reputation: 214959

Put the keys (in your case, name values) from the first array into a Set. Filter the second one and for each item, check if its key is in the set:

function intersectBy(a, b, keyFn) {
    let keys = new Set(a.map(keyFn));
    return b.filter(x => keys.has(keyFn(x)));
}

result = intersectBy(objectsToFind, findHere, x => x.name)

Code snippet:

var objectsToFind = [
  {
    name: "first",
    value: 1
  },
  {
    name: "second",
    value: 2
  },
  {
    name: "third",
    value: 3
  }
];
var findHere = [
  {
    name: "fourth",
    size: 36
  },
  {
    name: "second",
    size: 689
  },
  {
    name: "third",
    size: 47
  },
  {
    name: "sixth",
    size: 34
  }
];
function intersectBy(a, b, keyFn) {
  let keys = new Set(a.map(keyFn));
  return b.filter((x) => keys.has(keyFn(x)));
}

var result = intersectBy(objectsToFind, findHere, (x) => x.name);
console.log(result);

Upvotes: 1

Related Questions