如何从包含JavaScript重复项的数组中获取一组唯一值?

How to get an array of unique values from an array containing duplicates in JavaScript?

本问题已经有最佳答案,请猛点这里访问。

给定一个['0','1','1','2','3','3','3']数组,结果应该是['0','1','2','3']


编辑

ES6溶液:

1
[...new Set(a)];

替代方案:

1
Array.from(new Set(a));

老反应。o(n^2)(不要与大数组一起使用!)

1
2
3
4
5
6
var arrayUnique = function(a) {
    return a.reduce(function(p, c) {
        if (p.indexOf(c) < 0) p.push(c);
        return p;
    }, []);
};


如果你想维持秩序:

1
2
3
arr = arr.reverse().filter(function (e, i, arr) {
    return arr.indexOf(e, i+1) === -1;
}).reverse();

因为没有内置的反向索引,所以我反转数组,过滤掉重复项,然后重新反转它。

filter函数在当前索引之后(在原始数组中之前)查找元素的任何出现。如果找到一个,它就会抛出这个元素。

编辑:

或者,您可以使用lastindexof(如果您不关心订单):

1
2
3
arr = arr.filter(function (e, i, arr) {
    return arr.lastIndexOf(e) === i;
});

这将保留唯一的元素,但只保留最后一次出现的元素。这意味着['0'、'1'、'0']变为['1'、'0'],而不是['0'、'1']。


下面是一个数组原型函数:

1
2
3
4
5
6
7
8
9
Array.prototype.unique = function() {
    var unique = [];
    for (var i = 0; i < this.length; i++) {
        if (unique.indexOf(this[i]) == -1) {
            unique.push(this[i]);
        }
    }
    return unique;
};


带下划线

1
_.uniq([1, 2, 1, 3, 1, 4]); //=> [1, 2, 3, 4]


现在是2014年了,伙计们,时间的复杂性仍然很重要!

1
2
3
4
5
6
array.filter(function() {
  var seen = {};
  return function(element, index, array) {
    return !(element in seen) && (seen[element] = 1);
  };
}());

http://jspef.com/array-filter-unique/13


1
2
3
4
5
6
7
8
9
function array_unique(arr) {
    var result = [];
    for (var i = 0; i < arr.length; i++) {
        if (result.indexOf(arr[i]) == -1) {
            result.push(arr[i]);
        }
    }
    return result;
}

不是内置函数。如果产品列表不包含该项,请将其添加到唯一列表并返回唯一列表。


你走吧!不客气!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Array.prototype.unique = function()
{
    var tmp = {}, out = [];
    for(var i = 0, n = this.length; i < n; ++i)
    {
        if(!tmp[this[i]]) { tmp[this[i]] = true; out.push(this[i]); }
    }
    return out;
}

var a = [1,2,2,7,4,1,'a',0,6,9,'a'];
var b = a.unique();
alert(a);
alert(b);

您可以在这里找到所有类型的数组唯一实现:

http://jspef.com/distinct-hash-vs-comparison/12

http://jspef.com/array-unique-functional

我喜欢功能性风格,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var arr = ['lol', 1, 'fdgdfg', 'lol', 'dfgfg', 'car', 1, 'car', 'a', 'blah', 'b', 'c', 'd', '0', '1', '1', '2', '3', '3', '3', 'crazy', 'moot', 'car', 'lol', 1, 'fdgdfg', 'lol', 'dfgfg', 'car', 1, 'car', 'a', 'blah', 'b', 'c', 'd', '0', '1', '1', '2', '3', '3', '3', 'crazy', 'moot', 'car', 'lol', 1, 'fdgdfg'];

var newarr = arr.reduce(function (prev, cur) {
    //console.log(prev, cur);
    if (prev.indexOf(cur) < 0) prev.push(cur);
    return prev;
}, []);

var secarr = arr.filter(function(element, index, array){
    //console.log(element, array.indexOf(element), index);
    return array.indexOf(element) >= index;
});

//reverses the order
var thirdarr = arr.filter(function (e, i, arr) {
    //console.log(e, arr.lastIndexOf(e), i);
    return arr.lastIndexOf(e) === i;
});

console.log(newarr);
console.log(secarr);
console.log(thirdarr);


这是可行的。试试看。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function getUnique(a) {
  var b = [a[0]], i, j, tmp;
  for (i = 1; i < a.length; i++) {
    tmp = 1;
    for (j = 0; j < b.length; j++) {
      if (a[i] == b[j]) {
        tmp = 0;
        break;
      }
    }
    if (tmp) {
      b.push(a[i]);
    }
  }
  return b;
}

没有冗余的"返回"数组,没有ECMA5(我很确定!)简单易读。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function removeDuplicates(target_array) {
    target_array.sort();
    var i = 0;

    while(i < target_array.length) {
        if(target_array[i] === target_array[i+1]) {
            target_array.splice(i+1,1);
        }
        else {
            i += 1;
        }
    }
    return target_array;
}

1
2
3
4
5
6
7
8
9
10
11
function array_unique(nav_array) {
    nav_array = nav_array.sort(function (a, b) { return a*1 - b*1; });      
    var ret = [nav_array[0]];      
    // Start loop at 1 as element 0 can never be a duplicate
    for (var i = 1; i < nav_array.length; i++) {
        if (nav_array[i-1] !== nav_array[i]) {              
            ret.push(nav_array[i]);            
        }      
    }
    return ret;    
}


我喜欢用这个。使用for循环没有任何错误,我只是喜欢使用内置函数。您甚至可以为类型转换或非类型转换匹配传递一个布尔参数,在这种情况下,您将使用for循环(filter()方法/函数执行类型转换匹配(==)

1
2
3
4
5
6
7
8
9
10
Array.prototype.unique =
function()
{
    return this.filter(
        function(val, i, arr)
        {
            return (i <= arr.indexOf(val));
        }
    );
}

另一种方法是使用对象来初始存储阵列信息。然后再转换回来。例如:

1
2
3
4
5
6
7
8
9
var arr = ['0','1','1','2','3','3','3'];
var obj = {};

for(var i in arr)
    obj[i] = true;

arr = [];
for(var i in obj)
    arr.push(i);

变量"arr"现在包含["0"、"1"、"2"、"3"、"4"、"5"、"6"]


下面是从数组中删除重复值的方法。

1
2
3
4
5
6
7
8
9
10
function ArrNoDupe(dupArray) {
   var temp = {};
    for (var i = 0; i < dupArray.length; i++) {
         temp[dupArray[i]] = true;
         var uniqueArray = [];
       for (var k in temp)
           uniqueArray.push(k);
 return uniqueArray;
    }
}

你们中那些使用谷歌关闭库的人,有权使用goog.array.removeDuplicates,这和unique是一样的。不过,它改变了数组本身。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
    //
    Array.prototype.unique =
    ( function ( _where ) {
      return function () {
        for (
          var
          i1 = 0,
          dups;
          i1 < this.length;
          i1++
        ) {
          if ( ( dups = _where( this, this[i1] ) ).length > 1 ) {
            for (
              var
              i2 = dups.length;
              --i2;
              this.splice( dups[i2], 1 )
            );
          }
        }
        return this;
      }
    } )(
      function ( arr, elem ) {
        var locs  = [];
        var tmpi  = arr.indexOf( elem, 0 );
        while (
          ( tmpi ^ -1 )
          && (
            locs.push( tmpi ),
            tmpi = arr.indexOf( elem, tmpi + 1 ), 1
          )
        );
        return locs;
      }
    );
    //


1
2
3
4
5
6
7
Array.prototype.unique =function(){
    var uniqObj={};
    for(var i=0;i< this.length;i++){
      uniqObj[this[i]]=this[i];
    }
    return uniqObj;
}