是否有一种方法可以在JavaScript中返回两个数组之间的差异?

例如:

var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];

// need ["c", "d"]

当前回答

一个衬垫

const unique = (a) => [...new Set(a)]; const uniqueBy = (x,f)=>Object.values(x.reduce((a,b)=>((a[f(b)]=b),a),{})); const intersection = (a, b) => a.filter((v) => b.includes(v)); const diff = (a, b) => a.filter((v) => !b.includes(v)); const symDiff = (a, b) => diff(a, b).concat(diff(b, a)); const union = (a, b) => diff(a, b).concat(b); const a = unique([1, 2, 3, 4, 5, 5]); console.log(a); const b = [4, 5, 6, 7, 8]; console.log(intersection(a, b), diff(a, b), symDiff(a, b), union(a, b)); console.log(uniqueBy( [ { id: 1, name: "abc" }, { id: 2, name: "xyz" }, { id: 1, name: "abc" }, ], (v) => v.id )); const intersectionBy = (a, b, f) => a.filter((v) => b.some((u) => f(v, u))); console.log(intersectionBy( [ { id: 1, name: "abc" }, { id: 2, name: "xyz" }, ], [ { id: 1, name: "abc" }, { id: 3, name: "pqr" }, ], (v, u) => v.id === u.id )); const diffBy = (a, b, f) => a.filter((v) => !b.some((u) => f(v, u))); console.log(diffBy( [ { id: 1, name: "abc" }, { id: 2, name: "xyz" }, ], [ { id: 1, name: "abc" }, { id: 3, name: "pqr" }, ], (v, u) => v.id === u.id ));

打印稿

操场上的链接

const unique = <T>(array: T[]) => [...new Set(array)];


const intersection = <T>(array1: T[], array2: T[]) =>
  array1.filter((v) => array2.includes(v));


const diff = <T>(array1: T[], array2: T[]) =>
  array1.filter((v) => !array2.includes(v));


const symDiff = <T>(array1: T[], array2: T[]) =>
  diff(array1, array2).concat(diff(array2, array1));


const union = <T>(array1: T[], array2: T[]) =>
  diff(array1, array2).concat(array2);


const intersectionBy = <T>(
  array1: T[],
  array2: T[],
  predicate: (array1Value: T, array2Value: T) => boolean
) => array1.filter((v) => array2.some((u) => predicate(v, u)));


const diffBy = <T>(
  array1: T[],
  array2: T[],
  predicate: (array1Value: T, array2Value: T) => boolean
) => array1.filter((v) => !array2.some((u) => predicate(v, u)));


const uniqueBy = <T>(
  array: T[],
  predicate: (v: T, i: number, a: T[]) => string
) =>
  Object.values(
    array.reduce((acc, value, index) => {
      acc[predicate(value, index, array)] = value;
      return acc;
    }, {} as { [key: string]: T })
  );

其他回答

下面是另一个可以返回差异的解决方案,就像git diff一样:(它已经用typescript编写,如果你不使用typescript版本,只需删除类型)

/**
 * util function to calculate the difference between two arrays (pay attention to 'from' and 'to'),
 * it would return the mutations from 'from' to 'to' 
 * @param { T[] } from
 * @param { T[] } to
 * @returns { { [x in string]: boolean } } it would return the stringified version of array element, true means added,
 * false means removed
 */
export function arrDiff<T>(from: T[], to: T[]): { [x in string]: boolean } {

  var diff: { [x in string]: boolean } = {};
  var newItems: T[] = []
  diff = from.reduce((a, e) => ({ ...a, [JSON.stringify(e)]: true }), {})

  for (var i = 0; i < to.length; i++) {
    if (diff[JSON.stringify(to[i])]) {
      delete diff[JSON.stringify(to[i])]
    } else {
      newItems.push(to[i])
    }
  }

  return {
    ...Object.keys(diff).reduce((a, e) => ({ ...a, [e]: false }), {}),
    ...newItems.reduce((a, e) => ({ ...a, [JSON.stringify(e)]: true }), {})
  }
}

下面是一个用法示例:

arrDiff(['a', 'b', 'c'], ['a', 'd', 'c', 'f']) //{"b": false, "d": true, "f": true}

ES6中一个更简洁的方法是以下解决方案。

var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];

区别

a2.filter(d => !a1.includes(d)) // gives ["c", "d"]

十字路口

a2.filter(d => a1.includes(d)) // gives ["a", "b"]

析取联合(对称差分)

[ ...a2.filter(d => !a1.includes(d)),
  ...a1.filter(d => !a2.includes(d)) ]

所选的答案只对了一半。您必须比较数组的两种方式才能得到完整的答案。

const ids_exist = [
   '1234',
   '5678',
   'abcd',
]

const ids_new = [
  '1234',
  '5678',
  'efjk',
  '9999',
]

function __uniq_Filter (__array_1, __array_2) {
  const one_not_in_two = __array_1.filter(function (obj) {
    return __array_2.indexOf(obj) == -1
  })
  const two_not_in_one = __array_2.filter(function (obj) {
    return __array_1.indexOf(obj) == -1
  })
  return one_not_in_two.concat(two_not_in_one)
}

let uniq_filter = __uniq_Filter(ids_exist, ids_new)

console.log('uniq_filter', uniq_filter) // => [ 'abcd', 'efjk', '9999' ]
function diffArray(arr1, arr2) {
  const newArr = [];

// arr1 match to arr2
arr1.map((item)=>{
if(arr2.indexOf(item)<0){
  console.log(item)
  newArr.push(item)
}  
})

// arr2 match to arr1
arr2.map((item)=>{
if(arr1.indexOf(item)<0){
  newArr.push(item)
}
})

  return newArr; 
}

差异([1,2,3,5],[1,2,3,4,5])

输出::[4]

adaen对post(比较两个包含整数的数组JavaScript)的响应是关闭的:

有几个选项:

您可以将第二个数组的所有条目添加到hashmap中。然后遍历第一个数组中的条目,并记录hashmap中不存在的条目。

const arrOne = [2,3,10,7,9,15,7,15,21,1];
const arrTwo = [3,15,1,2,21];

const hash = {};

arrTwo.forEach(a => hash[a]++);
arrOne.filter(a => typeof hash[a] === 'undefined').forEach(a => console.log(a));

另一个选择是对两个数组进行排序。然后迭代第二个数组。在其中,迭代第一个数组。当您遇到第一个数组中的条目小于第二个数组中的下一个条目但不等于它时,您将它们注销。

const arrOne = [2,3,10,7,9,15,7,15,21,1].sort((a,b)=>a-b);
const arrTwo = [3,15,1,2,21].sort((a,b)=>a-b);

var i1 = 0;
for(var i2 = 0; i2 < arrTwo.length; i2++) {
  while(arrOne[i1] < arrTwo[i2+1]) {
    if(arrOne[i1] != arrTwo[i2]) {
      console.log(arrOne[i1]);
    }
    i1++;
  }
}