Matheus Barradas
Matheus Barradas

Reputation: 69

Return a subset of an array of objects that matches a property of an another array of objects

inputs:

const parentArray = [
{id:1, name:'foo'},
{id:2, name:'bar'},
{id:4, name:'foobar'},
{id:6, name:'barfoo'}
]

const childArray = [
  {parent_id:1, prop:'prop1'}, 
  {parent_id:2, prop:'prop2'}, 
  {parent_id:3, prop:'prop3'},
  {parent_id:4, prop:'prop4'},
  {parent_id:5, prop:'prop5'}
];

output:

const resultingArray = [
{id:1, name:'foo'},
{id:2, name:'bar'},
{id:4, name:'foobar'}
]

I want to compare the properties id and parent_id from both arrays and return a subset of parentArray for the matching properties

I've tried to filter them out but not having success, using lodash

Upvotes: 1

Views: 530

Answers (6)

Get Off My Lawn
Get Off My Lawn

Reputation: 36351

You can use a mixture of filter and some to get the matching values:

const parentArray = [{id:1, name:'foo'},{id:2, name:'bar'}]

const childArray = [
  {parent_id:1, prop:'prop1'}, 
  {parent_id:3, prop:'prop3'}
]

let result = parentArray.filter(i => childArray.some(j => j.parent_id == i.id))

console.log(result)

Upvotes: 0

Jorge Solis
Jorge Solis

Reputation: 1806

As previously mentioned, your example is unclear, but filtering an array using another array, assuming you want to use the properties id from parentArray and parent_id from childArray, then I would use this:

resultingArray = childArray.filter(c=> parentArray.find(p => p.id === c.parentId);

Upvotes: 0

Vandesh
Vandesh

Reputation: 6904

You can do so with a combination of Array.filter() and Array.some() in the following way.

const resultingArray = parentArray
                       .filter(x => childArray.some( y => y.parent_id===x.id));

Check this JS bin

Upvotes: 2

Amardeep Bhowmick
Amardeep Bhowmick

Reputation: 16908

We can use a Set as a lookup table for the parent_id data from the child and then use Array.prototype.filter to filter through the parent entries and use Set#has to check if the id is contained in the Set:

const parentArray = [{id:1, name:'foo'},{id:2, name:'bar'}, {id:4, name:'foo'},{id:6, name:'bar'}]

const childArray = [
  {parent_id:1, prop:'prop1'}, 
  {parent_id:2, prop:'prop2'}, 
  {parent_id:3, prop:'prop3'},
  {parent_id:4, prop:'prop4'},
  {parent_id:5, prop:'prop5'}
];

function findSubSet(){
  const lookup = new Set(childArray.map(({parent_id}) => parent_id));
  return parentArray.filter(p => lookup.has(p.id));
}
console.log(findSubSet(parentArray, childArray));

Upvotes: 2

Nina Scholz
Nina Scholz

Reputation: 386868

You could take a Set for the wanted parents and filter the parent array.

var parents = [{ id: 1, name: 'foo' }, { id: 2, name: 'bar' }],
    children = [{ parent_id: 1, prop: 'prop1' }, { parent_id: 3, prop: 'prop3' }],
    wanted = new Set(children.map(({ parent_id }) => parent_id)),
    result = parents.filter(({ id }) => wanted.has(id));

console.log(result);

Upvotes: 3

brk
brk

Reputation: 50346

You can use reduce & findIndex. In the reduce callback use findIndex to check if there exist same id.If id exist it will return the index & if not then it will return -1. So if index is not -1 then you can push the value to accumulator(acc)

const parentArray = [{
  id: 1,
  name: 'foo'
}, {
  id: 2,
  name: 'bar'
}]

const childArray = [{
    parent_id: 1,
    prop: 'prop1'
  },
  {
    parent_id: 2,
    prop: 'prop2'
  },
  {
    parent_id: 3,
    prop: 'prop3'
  }
]

let filteredData = parentArray.reduce(function(acc, curr) {
  let getIndexFromChild = childArray.findIndex(function(item) {
    return curr.id === item.parent_id
  });

  if (getIndexFromChild !== -1) {
    acc.push(curr)
  }

  return acc;
}, []);

console.log(filteredData)

Upvotes: 0

Related Questions