Home > Net >  Filter out array using another array of objects
Filter out array using another array of objects

Time:09-02

I am having two arrays

const selected = [];
const current = [
  { id: 1, name: "abc" },
  { id: 2, name: "def" }
];
const result = []

I need to compare these two arrays and the result should only have the single entry instead of duplicates. In the above example result should have the following output.

Also items in the selected should be taken into consideration and should be in the beginning of the result

result = [
  { id: 1, name: "abc" },
  { id: 2, name: "def" }
];

Also when the input is following

const selected = [ {id:5, name: "xyz" }];
const current = [
  { id: 1, name: "abc" },
  { id: 2, name: "def" }
];
result = [[
  { id: 5, name: "xyz" },
  { id: 1, name: "abc" },
  { id: 2, name: "def" }
];

Also when the input is following

const selected = [ {id:1, name: "abc" }, {id:4, name: "lmn" }];
const current = [
  { id: 1, name: "abc" },
  { id: 2, name: "def" }
];
result = [[
  { id: 1, name: "abc" },
  { id: 4, name: "lmn" }
  { id: 2, name: "def" }
];

Note the comparison should be made using name field

Code that I tried

const res = [...(selected || [])].filter((s) =>
  current.find((c) => s.name === c.name)
);

Sandbox: https://codesandbox.io/s/nervous-shannon-j1vn5k?file=/src/index.js:115-206

CodePudding user response:

You could get all items and filter the array by checking the name with a Set.

const
    filterBy = (key, s = new Set) => o => !s.has(o[key]) && s.add(o[key]),
    selected = [{ id: 1, name: "abc" }, { id: 1, name: "lmn" }],
    current = [{ id: 1, name: "abc" }, { id: 2, name: "def" }],
    result = [...selected, ...current].filter(filterBy('name'));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

CodePudding user response:

Loop through selected, and if there is no object in current with a name that matches the name of the object in the current iteration push it into current.

const selected=[{id:1,name:"abc"},{id:6,name:"def"},{id:4,name:"lmn"}];
const current=[{id:1,name:"abc"},{id:2,name:"def"}];

for (const sel of selected) {
  const found = current.find(cur => cur.name === sel.name);
  if (!found) current.push(sel);
}

console.log(current);

CodePudding user response:

This is a good use for .reduce, avoids multiple loops/finds and doesn't need filtering with side-effects.

const selected = [ {id:1, name: "abc" }, {id:4, name: "lmn" }];
const current = [
  { id: 1, name: "abc" },
  { id: 2, name: "def" }
];

const result = Object.values(
  [...selected, ...current].reduce((obj, item) => {
    obj[item.name] = obj[item.name] || item;
    return obj;
  }, {})
)

console.log(result);

  • Related