我需要检查一个JavaScript数组,看看是否有任何重复的值。最简单的方法是什么?我只需要找到复制的值是什么——实际上我不需要它们的索引,也不需要它们复制了多少次。

我知道我可以循环遍历数组并检查所有其他值是否匹配,但似乎应该有更简单的方法。

类似的问题:

获取JavaScript数组中所有唯一的值(删除重复值)


当前回答

在这里,每个dupe只输出一次副本。

Var arr = [9,9,9,9,111, 2,3,4,4,5,7]; arr.sort (); Var结果= []; For (var I = 0;我< arr。长度- 1;我+ +){ 如果(arr[i + 1] == arr[i]) { results.push (arr[我]); } } results = Array.from(new Set(results)) console.log(结果);

其他回答

您可以对数组进行排序,然后遍历它,然后查看下一个(或上一个)索引是否与当前索引相同。假设你的排序算法是好的,这个应该小于O(n2):

const findDuplicates = (arr) => { let sorted_arr = arr.slice().sort(); // You can define the comparing function here. // JS by default uses a crappy string compare. // (we use slice to clone the array so the // original array won't be modified) let results = []; for (let i = 0; i < sorted_arr.length - 1; i++) { if (sorted_arr[i + 1] == sorted_arr[i]) { results.push(sorted_arr[i]); } } return results; } let duplicatedArray = [9, 9, 111, 2, 3, 4, 4, 5, 7]; console.log(`The duplicates in ${duplicatedArray} are ${findDuplicates(duplicatedArray)}`);

在这种情况下,如果你要返回一个重复的函数。这是为类似类型的情况。

参考:https://stackoverflow.com/a/57532964/8119511

从数组/字符串中获取重复/重复值的最简单方法:

函数getduplicate (param) { Var duplicate = {} For (var I = 0;I < param.length;我+ +){ Var char = param[i] 如果(重复[char]) { 副本(char) + + }其他{ duplicate [char] = 1 } } 返回副本 } console.log (getDuplicates(“aeiouaeiou”)); console.log (getDuplicates((“a”、“e”、“我”、“o”、“u”,“一个”,“e”))); console.log(getduplicate ([1,2,3,4,5,1,1,2,3]));

我试过了,你会得到唯一的元素和在两个不同数组中重复的元素。

复杂度O (n)

let start = [1,1,2,1,3,4,5,6,5,5]; start.sort(); const unique=[]; const repeat = []; let ii=-1 ; for(let i =0 ; i<start.length; i++){ if(start[i]===start[i-1]){ if(repeat[ii]!==start[i-1]){ repeat.push(start[i-1]); ii++; } } else { if(i+1<start.length){ if(start[i]!==start[i+1]){ unique.push(start[i]); } } else if(i===start.length-1){ unique.push(start[i]); } } } console.log(unique) ; console.log(repeat);

更新:简短的一行程序,以获得副本:

[1, 2, 2, 4, 3, 4].filter((e, i, a) => a.indexOf(e) !== i) // [2, 4]

要获得没有重复项的数组,只需反转条件:

[1, 2, 2, 4, 3, 4].filter((e, i, a) => a.indexOf(e) === i) // [1, 2, 3, 4]

注意,这个答案的主要目标是简短。如果你需要一个大数组的性能,一个可能的解决方案是先排序你的数组(如果它是可排序的),然后执行以下操作来获得与上面相同的结果:

myHugeSortedArray.filter((e, i, a) => a[i-1] === e)

下面是一个1 000 000个整数数组的例子:

const myHugeIntArrayWithDuplicates =
  [...Array(1_000_000).keys()]
  // adding two 0 and four 9 duplicates
  .fill(0, 2, 4).fill(9, 10, 14)

console.time("time")
console.log(
  myHugeIntArrayWithDuplicates
  // a possible sorting method for integers
  .sort((a, b) => a > b ? 1 : -1)
  .filter((e, i, a) => a[i-1] === e)
)
console.timeEnd("time")

在我的AMD Ryzen 7 5700G开发机上输出:

[ 0, 0, 9, 9, 9, 9 ]
time: 22.738ms

正如在评论中指出的那样,短解决方案和性能解决方案都将返回一个具有多次相同副本的数组,如果它在原始数组中出现多次:

[1, 1, 1, 2, 2, 2, 2].filter((e, i, a) => a.indexOf(e) !== i) // [1, 1, 2, 2, 2]

如果需要唯一的副本,则函数为

function duplicates(arr) {
  return [...new Set(arr.filter((e, i, a) => a.indexOf(e) !== i))]
}

可以使用duplicate([1, 1, 1, 2, 2, 2, 2])返回[1,2]。


当你所需要的只是检查是否像这个问题中要求的那样没有重复时,你可以使用every()方法:

[1, 2, 3].every((e, i, a) => a.indexOf(e) === i) // true

[1, 2, 1].every((e, i, a) => a.indexOf(e) === i) // false

注意,every()在ie8及以下版本中不起作用。

仅ES5(即,它需要一个filter() polyfill用于IE8及以下):

var arrayToFilter = [ 4, 5, 5, 5, 2, 1, 3, 1, 1, 2, 1, 3 ];

arrayToFilter.
    sort().
    filter( function(me,i,arr){
       return (i===0) || ( me !== arr[i-1] );
    });