根据underscore.js文档:
uniq _.uniq(array, [isSorted], [iteratee])
别名: unique
制作一个无重复的数组版本,使用===来测试对象的相等性。如果你事先知道数组是排序过的,传入true给isSorted
将运行更快的算法。如果要基于一个转换计算独特的项,则传递迭代器函数。
但在JavaScript中,数组不能严格比较。
因此,您可以使用转换函数使uniq
能够进行比较。例如:
console.log([1,2] === [1,2])
console.log([1,2].toString())
console.log([1,2].toString() === [1,2].toString())
var valueToString = function(v) {return v.toString()};
var arr1 = [[1,2], [2,3], [1,2]];
var arr2 = _.uniq(arr1, false, valueToString);
var arraysAreEqual = _.isEqual(arr1, arr2);
console.log("arraysAreEqual:", arraysAreEqual, arr1, arr2);
请注意,将数组转换为字符串是“hacky”的做法:最好比较数组的每个值,如
此StackOverflow问题中所讨论的那样。
通过使用该问题中提出的
equals
实现,您需要实现自己的
uniq
版本,该版本使用
equals
而不是
===
。
Underscore中
uniq
的
实现非常简单 - 它创建一个新的
result
数组并循环遍历给定数组。如果当前值尚未在结果中,则插入它。
console.log("Using array comparison:");
arrayEquals = function (array1, array2) {
if (!array1 || !array2)
return false;
if (array1.length != array2.length)
return false;
for (var i = 0, l=array1.length; i < l; i++) {
if (array1[i] instanceof Array && array2[i] instanceof Array) {
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);
var existing = _.find(result, arrayEqualsToValue);
if (!existing) {
result.push(value);
}
}
return result;
};
var arr3 = _.uniqArrays(arr1);
arraysAreEqual = _.isEqual(arr1, arr3);
console.log("arraysAreEqual:", arraysAreEqual, arr1, arr3);
如果您想尝试一下,我已经在jsbin上放置了所有代码。