在 JavaScript 中查找嵌套的重复数组.(嵌套数组 uniq in lodash/underscore)



我正在尝试确定JavaScript数组是否包含重复项。这可能吗?我首先尝试看看是否可以去除重复项,然后进行相等性检查,但我无法通过第一部分。以下是下划线返回的内容:

var arr1 = [[1,2], [2,3], [1,2]];
var arr2 = _.uniq(arr1);
var arraysAreEqual = _.isEqual(arr1, arr2);
console.log(arraysAreEqual, arr1, arr2);
// true

杰斯宾: http://jsbin.com/vogumo/1/edit?js,console

有人知道确定数组是否包含重复数组的方法吗?

这有点草率,但是(可能)

var arr2 = _.uniq(arr1, function(item) {
    return JSON.stringify(item);
});

会给你一个正确的结果

试试这个:

var numArray = [1, 7, 3, 0, 9, 7, 8, 6, 2, 3];
var duplicates = [];
var sortednumArray = numArray.sort();

for (var i = 0; i < sortednumArray.length; i++) {
    //console.log(sortednumArray[i]);
    if (sortednumArray[i] == sortednumArray[i + 1]) {
        duplicates.push(sortednumArray[i]);
    }
}
if (duplicates.length == 0) {
    console.log("Soted Array:");
    for(var i = 0; i < sortednumArray.length; i++) {
        console.log(sortednumArray[i]);
    }
} else {
    console.log("Duplicates:");
    for(var i = 0; i < duplicates.length; i++){
        console.log(duplicates[i]);
    }
}

程序将所有重复项推送到名为"重复项"的数组中,然后显示它,但如果不存在,则显示 numArray 的排序版本

从下划线.js文档中:

优尼克_.uniq(array, [isSorted], [iteratee])别名唯一
产生一个 数组的无重复版本,使用 === 测试对象 平等。如果您事先知道数组已排序,则传递 对于isSorted来说,将运行更快的算法。如果你愿意 基于转换计算唯一项,传递迭代 函数

但是数组不能在JavaScript中严格比较。

因此,您可以使用转换函数来启用与uniq 的比较。例如:

console.log([1,2] === [1,2]) // false, can't strict compare arrays
console.log([1,2].toString()) // "1,2" - string representation
console.log([1,2].toString() === [1,2].toString()) // true, strings can be compared
var valueToString = function(v) {return v.toString()}; // transform array to string
var arr1 = [[1,2], [2,3], [1,2]];
var arr2 = _.uniq(arr1, false, valueToString); // compare based on transformation
var arraysAreEqual = _.isEqual(arr1, arr2);
console.log("arraysAreEqual:", arraysAreEqual, arr1, arr2); 
// false
// [[1, 2], [2, 3], [1, 2]]
// [[1, 2], [2, 3]]

请注意,转换为字符串是"黑客":你最好比较数组的每个值,如这个StackOverflow问题中所讨论的那样。

通过使用该问题中建议的equals实现,您需要实现自己的使用 equals 而不是 ===uniq版本。

Uniq 在 Underscore 中的实现非常简单 - 它创建一个新的result数组并循环访问给定的数组。如果结果中尚未显示当前值,请将其插入。

console.log("Using array comparison:");
arrayEquals = function (array1, array2) {
    // if any array is a falsy value, return
    if (!array1 || !array2)
        return false;
    // compare lengths - can save a lot of time 
    if (array1.length != array2.length)
        return false;
    for (var i = 0, l=array1.length; i < l; i++) {
        // Check if we have nested arrays
        if (array1[i] instanceof Array && array2[i] instanceof Array) {
            // recurse into the nested arrays
            if (!arrayEquals(array1[i],array2[i]))
                return false;       
        }           
        else if (array1[i] !== array2[i]) { 
            return false;   
        }        
    }       
    return true;
};
_.uniqArrays = function(array) {
  if (array == null) return [];
  var result = [];
  for (var i = 0, length = array.length; i < length; i++) {
    var value = array[i];
    var arrayEqualsToValue = arrayEquals.bind(this, value); // arrayEquals with first argument set to value
    var existing = _.find(result, arrayEqualsToValue); // did we already find this?
    if (!existing) {
      result.push(value);
    }
  }
  return result;
};
var arr3 = _.uniqArrays(arr1);
arraysAreEqual = _.isEqual(arr1, arr3);
console.log("arraysAreEqual:", arraysAreEqual, arr1, arr3); // false
如果你想玩的话

,我用所有代码做了一个jsbin。

在最新的 lodash (4.6.1) 中,您可以执行以下操作:

if (_.uniqWith(arr, _.isEqual).length < arr.length) {
  // then there were duplicates
}

最新更新