JavaScript比较2个数组并使用对象中的键值对查找唯一值

时间:2015-10-30 06:26:34

标签: javascript arrays

我正在编写一个diff(arr1,arr2)函数来比较两个数组,并返回一个新数组,其中包含两个原始数组中都找不到的任何项。

示例:

diff([1, 2, 3, 5], [1, 2, 3, 4, 5]) 
// [4]

diff([1, "calf", 3, "piglet"], [7, "filly"])
// [1, "calf", 3, "piglet", 7, "filly"]

我的解决方案是使用数组中的唯一值作为键来构建对象,并将频率作为该键的值。然后我将值为1的密钥收集到一个新数组中。

问题:我认为密钥被视为对象中的字符串这一事实使我的解决方案不是很优雅,因为我需要使用Number()来转换"整数"密钥从字符串到数字。

问题:我的代码有效,但在比较2个数组后,是否有人有更好的解决方案来查找唯一值?

我的代码:

function diff(arr1, arr2) {

  var newArr = arr1.concat(arr2);
  var dict = {};

  for (var i = 0; i < newArr.length; i++) {
    if (!dict[newArr[i]]) {
      dict[newArr[i]] = 1;
    }
    else {
      dict[newArr[i]]++;
    } 

  }

  var unique = [];

  for (var key in dict) {
    if (dict[key] === 1) {
      if (!Number(key)) {
        unique.push(key);
      }
      else {
        unique.push(Number(key));
      }
    }
  }
  return unique;
}

感谢您的帮助=)

4 个答案:

答案 0 :(得分:2)

如果您可以使用underscore.js,则可以实施以下diff功能。

function diff (arr1, arr2) {
  return _.difference(arr1, arr2).concat(_.difference(arr2, arr1));
}

答案 1 :(得分:2)

不考虑性能问题,可以写成:

function complement(a1, a2) { return a1.filter(v => !a2.includes(v)); }
function union     (a1, a2) { return a1.concat(a2); }

function difference(a1, a2) { return union( complement(a1, a2), complement(a2, a1) ); }

您需要一个支持Array#includes或polyfill的环境,或者自己编写:

function complement(a1, a2) { return a1.filter(v => a2.indexOf(v) === -1); }

答案 2 :(得分:1)

这是一个纯粹的JS解决方案:

var diff = function(array1, array2) {
    var simmetricDifference = [];

    var getMissedItems = function(sourceArray, searchInArray) {
        sourceArray.forEach(function(item) {
            if((searchInArray.indexOf(item) === -1) && (simmetricDifference.indexOf(item) === -1)) {
                simmetricDifference.push(item);
            }
        });
    };

    getMissedItems(array1, array2);
    getMissedItems(array2, array1);

    return simmetricDifference;
};

答案 3 :(得分:1)

问题实际上是指symmetric difference功能。使用_.xor