从JS数组中移除重复值

2348

我有一个非常简单的JavaScript数组,可能包含重复项。

var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];

我需要删除重复项并将唯一值放入一个新数组。

我可以指出我尝试过的所有代码,但我认为这没有用,因为它们不起作用。我接受jQuery解决方案。

类似问题:


95
_.uniq(peoplenames) 解决了这个问题。请参考 http://lodash.com/docs#uniq 了解更多信息。 - Connor Leech
10
@ConnorLeech 使用 lodash 很容易,但这不是最优化的方式。 - Suhail Mumtaz Awan
45
我认为最简单的方法是使用Set对象,它可以存储任何类型的唯一值。换句话说,Set会自动帮我们删除重复的元素。`const names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];let unique = [...new Set(names)]; console.log(unique); // 'Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Carl'` - Asif vora
13
世界上有太多叫Mike的人了——为什么不把他们移除掉呢?Nancy在这件事上被打败了。 - toad
3
在我的解决方案中,我会在过滤之前对数据进行排序:const result = data.sort().filter((v, idx, t) => idx==0 || v != t[idx-1]); - Didier68
显示剩余10条评论
54个回答

4

https://jsfiddle.net/2w0k5tz8/

function remove_duplicates(array_){
    var ret_array = new Array();
    for (var a = array_.length - 1; a >= 0; a--) {
        for (var b = array_.length - 1; b >= 0; b--) {
            if(array_[a] == array_[b] && a != b){
                delete array_[b];
            }
        };
        if(array_[a] != undefined)
            ret_array.push(array_[a]);
    };
    return ret_array;
}

console.log(remove_duplicates(Array(1,1,1,2,2,2,3,3,3)));

循环遍历数组,去除重复项,并创建一个克隆数组占位符,因为数组索引不会被更新。

为了更好的性能,反向循环(您的循环将不需要不断检查数组长度)。


3
这只是另一种解决方案,但与其他的不同。
function diffArray(arr1, arr2) {
  var newArr = arr1.concat(arr2);
  newArr.sort();
  var finalArr = [];
  for(var i = 0;i<newArr.length;i++) {
   if(!(newArr[i] === newArr[i+1] || newArr[i] === newArr[i-1])) {
     finalArr.push(newArr[i]);
   } 
  }
  return finalArr;
}

3

使用ES5的Object.keys方法是一种不需要写很多代码的方法:

var arrayWithDuplicates = ['a','b','c','d','a','c'],
    deduper = {};
arrayWithDuplicates.forEach(function (item) {
    deduper[item] = null;
});
var dedupedArray = Object.keys(deduper); // ["a", "b", "c", "d"]

从函数中提取

function removeDuplicates (arr) {
    var deduper = {}
    arr.forEach(function (item) {
        deduper[item] = null;
    });
    return Object.keys(deduper);
}

这个不起作用。你没有在任何地方使用 arrayWithDuplicates - Oriol
@Oriol 对不起,我忘记了一行代码。我已经编辑了这个例子。 - Willem de Wit

3

对于任何想要将具有重复元素的数组展平为一个唯一数组的人:

function flattenUniq(arrays) {
  var args = Array.prototype.slice.call(arguments);

  var array = [].concat.apply([], args)

  var result = array.reduce(function(prev, curr){
    if (prev.indexOf(curr) < 0) prev.push(curr);
    return prev;
  },[]);

  return result;
}

在 reduce 方法后添加空数组的目的是什么? - Austin737

2
function arrayDuplicateRemove(arr){
    var c = 0;
    var tempArray = [];
    console.log(arr);
    arr.sort();
    console.log(arr);
    for (var i = arr.length - 1; i >= 0; i--) {
        if(arr[i] != tempArray[c-1]){
            tempArray.push(arr[i])
            c++;
        }
    };
    console.log(tempArray);
    tempArray.sort();
    console.log(tempArray);
}

2
最简单的删除重复数据的方法是使用for循环比较不同的元素,并将它们推入新数组中。
 var array = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];

 var removeDublicate = function(arr){
 var result = []
 var sort_arr = arr.sort() //=> optional
 for (var i = 0; i < arr.length; i++) {
        if(arr[ i + 1] !== arr[i] ){
            result.push(arr[i])
        }
 };
  return result
}  
console.log(removeDublicate(array))
==>  ["Adam", "Carl", "Jenny", "Matt", "Mike", "Nancy"]

2

这可能是从数组中永久删除重复项的最快方法之一,比这里大多数函数快10倍。在safari中快78倍。

function toUnique(a,b,c){               //array,placeholder,placeholder
 b=a.length;while(c=--b)while(c--)a[b]!==a[c]||a.splice(c,1)
}
  1. 测试:http://jsperf.com/wgu
  2. 演示:http://jsfiddle.net/46S7g/
  3. 更多信息:https://stackoverflow.com/a/25082874/2450730

如果您无法阅读上面的代码,请阅读一本JavaScript书,或者在此处了解更多关于简短代码的说明:https://dev59.com/eXI-5IYBdhLWcg3wqqXh#21353032


7
我猜这是因为把压缩过的代码作为解决方案发布了... - Mark K Cowan
2
如果你在使用while循环和splice(这也是一个循环)时声称自己是“最快”的,那么你应该会被downvote。最快的方法是使用哈希映射(JS-Object)和单个循环,时间复杂度为O(n)。尝试只使用hasOwnProperty(),push()和forEach()编写函数,它将会很快。参见:https://en.wikipedia.org/wiki/Big_O_notation - cat
从我所做的测试和阅读许多其他网站的内容来看... 直接设置比推送(x[0] vs x.push())更快,forEach 比 while 慢得多,并且如果您不搞乱数组,则 hasOwnProperty() 是无用的。但是,如果您发布一个更快的代码,我会很高兴。您也可以投反对票。无论如何,我以许多不同的方式编写了该函数,即使我发现这个函数也很奇怪,但在大多数浏览器上,这个函数在普通数组上给出了最佳结果。 - cocco
我所说的普通数组指的是10-100000个元素的范围。请注意...我很乐意找到更好的方法,因为我正在使用这个函数,而且我也是一个试图避免无用循环的人。请查看我的其他函数。 - cocco
在这里,最快是指基于此特定帖子中列出的代码而言的最快代码。复制并粘贴这些代码,然后自己尝试一下... 这里没有任何一个代码比这个奇怪的whilewhile函数更快。 - cocco
我可以建议添加空格和缩进以使其更易读吗? - McKay M

1

我知道我有点晚了,但这里有另一个选项,使用jinqJs

查看Fiddle

var result = jinqJs().from(["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"]).distinct().select();

1

嵌套循环方法用于在数组中删除重复元素并保留原始元素顺序。

var array = [1, 3, 2, 1, [5], 2, [4]]; // INPUT

var element = 0;
var decrement = array.length - 1;
while(element < array.length) {
  while(element < decrement) {
    if (array[element] === array[decrement]) {
      array.splice(decrement, 1);
      decrement--;
    } else {
      decrement--;
    }
  }
  decrement = array.length - 1;
  element++;
}

console.log(array);// [1, 3, 2, [5], [4]]

解释: 内部循环将数组的第一个元素与从最高索引处开始的所有其他元素进行比较。向第一个元素递减时,会从数组中拼接出一个重复项。

当内部循环完成后,外部循环将增加到下一个元素进行比较,并重置数组的新长度。


1
使用reduce和find的方式。

const numbers = [1, 1, 2, 3, 4, 4];

function unique(array) {
  return array.reduce((a, b) => {
    let isIn = a.find(element => {
      return element === b;
    });
    if (!isIn) {
      a.push(b);
    }
    return a;
  }, []);
}

let ret = unique(numbers); // [1, 2, 3, 4]
console.log(ret);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接