admin管理员组

文章数量:1435859

So I'm looking to achieve this in vanilla, ES6 JS. Please no jQuery! (Lodash is acceptable!)

Basically I have 2 arrays, 1 that contains objects, and 1 that contains ids.

const old = [
  {
    id: 1,
    name: 'object_1',
  },
  {
    id: 2,
    name: 'object_2',
  },
];

const newIds = [1, 2, 3];

My current solution to this problem is as shown;

const difference = newIds.filter(n => !old.some(o => o.id === n));

This results in the return [3].

Basically I'm currently using this to determine if something is missing, and create it in my database if it is missing.

However, I need to then do the opposite. If something is removed, I need to pare and remove the item.

The problem with this is; This current solution only works "1 way" so I'm unable to do what I stated above.

Ideally I only want 1 statement whether it's creation or deletion, and I only want it to return the id's of stuff that is missing from either array.

Hopefully that makes sense.

So I'm looking to achieve this in vanilla, ES6 JS. Please no jQuery! (Lodash is acceptable!)

Basically I have 2 arrays, 1 that contains objects, and 1 that contains ids.

const old = [
  {
    id: 1,
    name: 'object_1',
  },
  {
    id: 2,
    name: 'object_2',
  },
];

const newIds = [1, 2, 3];

My current solution to this problem is as shown;

const difference = newIds.filter(n => !old.some(o => o.id === n));

This results in the return [3].

Basically I'm currently using this to determine if something is missing, and create it in my database if it is missing.

However, I need to then do the opposite. If something is removed, I need to pare and remove the item.

The problem with this is; This current solution only works "1 way" so I'm unable to do what I stated above.

Ideally I only want 1 statement whether it's creation or deletion, and I only want it to return the id's of stuff that is missing from either array.

Hopefully that makes sense.

Share Improve this question edited Mar 20, 2019 at 5:04 asked Mar 20, 2019 at 4:58 user5113508user5113508 3
  • 1 Since you wrote "Lodash is acceptable", add the lodash tag in your question: that way, the question will show up for users following (or "watching") that tag. – Gerardo Furtado Commented Mar 20, 2019 at 5:00
  • 1 if you don't want to build plex logic you can easily find the difference of array using lodash js library – Sanjaysinh Zala Commented Mar 20, 2019 at 5:01
  • @SanjaysinhZala Perhaps an example? I tried use Lodash difference method but wasn't working how I wanted it to. – user5113508 Commented Mar 20, 2019 at 5:04
Add a ment  | 

7 Answers 7

Reset to default 5

To find the values that appear in one but not the other use lodash's

_.xor(array1, array2);

In your case:

> const _ = require('lodash');

> const old = [
...   { id: 1, name: 'object_1' },
...   { id: 2, name: 'object_2' },
...   { id: 3, name: 'object_3' },
...   { id: 4, name: 'object_4' },
... ];

> const newIds = [1, 3, 5, 7];

> _.xor(old.map(x => x.id), newIds)
[ 2, 4, 5, 7 ]

We can do the same in vanilla es6 by using Array#filter and Array#includes.

Here, I have mapped the old array to only an array of ids by using Array#map and then using the filter and includes on both the arrays I have found out the symmetric difference between them.

const old = [
  {
    id: 1,
    name: 'object_1',
  },
  {
    id: 2,
    name: 'object_2',
  },
];
const newIds = [2, 3];
const oldIds =  old.map(({id}) => id);

console.log(getDifference(oldIds, newIds));

function getDifference(oldIds, newIds){
  const diff = [...oldIds.filter(id => !newIds.includes(id)), ...newIds.filter(id => !oldIds.includes(id))];
  return diff;
}

We can do it another way using Array#reduce and Array#findIndex. Just reduce over both the arrays and return the elements which are not repeated more than once will give us the symmetric difference of the two arrays.

const old = [
  {
    id: 1,
    name: 'object_1',
  },
  {
    id: 2,
    name: 'object_2',
  },
];
const newIds = [2, 3];
const oldIds =  old.map(({id}) => id);

console.log(getDifference(oldIds, newIds));

function getDifference(oldIds, newIds){
  return [...oldIds, ...newIds].reduce((acc, ele) => {
  if(!acc.includes(ele)){
     acc.push(ele);
  }else{
    acc.splice(acc.findIndex(e=> ele === e), 1);
  }
  return acc;
  },[]);
}

Hope this helps. I know this not excatly what you want, but this can be one work around.

const old = [
  {
    id: 1,
    name: 'object_1',
  },
  {
    id: 2,
    name: 'object_2',
  },
  {
    id: 4,
    name: 'object_2',
  },
];

const newIds = [1, 2, 3];

var x1 = old.filter(x => !newIds.includes(x.id)).map(z => z.id)
             .concat(newIds.filter(x => !old.some(y => y.id === x)));
console.log(x1);

Here is the solution using ES6:

const old = [
  {
    id: 1,
    name: 'object_1',
  },
  {
    id: 2,
    name: 'object_2',
  },
  {
    id: 4,
    name: 'object_2',
  },
];

const newIds = [1, 2, 3];
const oldIds = old.map(o => o.id)

const difference = [...newIds.filter(id => oldIds.indexOf(id) === -1), ...oldIds.filter(id => newIds.indexOf(id) === -1)]

console.log(difference)

You can use xor function from lodash to get this. Before that, you can collect all the ids from the oldarray and use that ids array for xor.

Check this out.

const { xor } = _;
const old = [
  {
    id: 1,
    name: 'object_1',
  },
  {
    id: 2,
    name: 'object_2',
  },
  {
    id: 4,
    name: 'object_4',
  },
];

const newIds = [1, 2, 3];
const oldIds = old.map(o => o.id)
const diff = xor(newIds, oldIds);
console.log(diff)
<script src="https://cdnjs.cloudflare./ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

You could use _.get with a default value as an iteratee for _.differenceBy so that either the array of objects or the array of numbers could be on the left hand side.

const old = [
  {
    id: 1,
    name: 'object_1',
  },
  {
    id: 2,
    name: 'object_2',
  },
];

const newIds = [1, 2, 3];

const diff = (a,b) => _.differenceBy(a, b, v => _.get(v, 'id', v))
console.log({ remove: diff(old, newIds), add: diff(newIds, old) })

const otherNewIds = [1];
console.log({ remove: diff(old, otherNewIds), add: diff(otherNewIds, old) })
<script src="https://cdnjs.cloudflare./ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

The following code will find the difference using lodash:

const difference = _.difference(newIds, _.map(old, 'id'));

本文标签: javascriptHow to compare two arrays and return the difference (Working both ways)Stack Overflow