【问题标题】:How to get an array of unique values from an array containing duplicates in JavaScript? [duplicate]如何从包含 JavaScript 中重复项的数组中获取唯一值数组? [复制]
【发布时间】:2012-11-09 07:17:31
【问题描述】:

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

【问题讨论】:

  • 是的,jquery 解决了所有问题。
  • 您可以使用像 underscore.js underscorejs.org/#uniq 这样的实用程序库来进行这些“简单”的操作
  • 哦,重复问题的讽刺。
  • @LucioPaiva 重复问题的数组在哪里??? ????????????

标签: javascript arrays unique


【解决方案1】:

编辑

ES6 解决方案:

[...new Set(a)];

替代方案:

Array.from(new Set(a));

旧响应。 O(n^2)(不要将它用于大型数组!)

var arrayUnique = function(a) {
    return a.reduce(function(p, c) {
        if (p.indexOf(c) < 0) p.push(c);
        return p;
    }, []);
};

【讨论】:

  • 废话!您确实需要使用分号! jsfiddle.net/bTNc2
  • 现在是 2014 年,所以我们又需要分号了。
  • 现在是 2015 年,所以我们不再需要分号了。
  • 2016 年我们需要使用分号吗?
  • 现在是 2016 年的中段,而且大部分时间是 semicolons are optional but highly encouraged 年。
【解决方案2】:

如果你想维持秩序:

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

由于没有内置的反向索引,我将数组反转,过滤掉重复项,然后重新反转它。

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

编辑:

或者,您可以使用 lastindexOf (如果您不关心顺序):

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

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

【讨论】:

  • 有趣的解决方案,lastIndexOf 有效吗?
  • 有点意思,但这取决于你的意思。如果您不需要 order 而不是 reverse() hack,则可以使用它。
  • +1 用于打高尔夫球。不幸的是,直接的for 循环似乎表现更好JSPerf。该死的函数调用太贵了。
  • @merv - OP 对性能只字未提,所以我很有创意。代码很简单,不是吗?
  • 不错!不过我更喜欢[1,2,3,1,1].filter(function(elem,idx,arr){ return arr.indexOf(elem) &gt;= idx; });,它更直接
【解决方案3】:

这是一个数组原型函数:

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;
};

【讨论】:

  • 这是最容易阅读的代码XD
【解决方案4】:

underscorejs

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

【讨论】:

  • 这对数组数组有用吗
【解决方案5】:

现在是 2014 年,时间复杂度仍然很重要!

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

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

【讨论】:

    【解决方案6】:
    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;
    }
    

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

    【讨论】:

    • 可能要提一下,这在 IE8 或更低版本中不起作用..
    • 为什么不能在 IE8 中运行?
    • 可能是因为少了一个右括号,应该是:result.push(arr[i]);
    【解决方案7】:

    给你!不客气!

    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);
    

    【讨论】:

      【解决方案8】:

      你可以在这里找到各种数组唯一的实现:

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

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

      我更喜欢功能样式,例如:

      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);
      

      【讨论】:

      • 我认为大多数提出的解决方案都有一个潜在的问题,因为它们是计算密集型的。他们至少需要 O(n^2) 操作(由于每次迭代都调用 indexOf)。因此,当使用小型阵列时它很好,但不适用于大型阵列。我在这里发表此评论是因为有一个性能测试链接,我认为由于数据太小而具有误导性。
      • 这里有一个更好的性能研究:shamasis.net/2009/09/…
      • @terrinecold 太棒了,您应该发布一个引用该答案的答案。如果javascript编译器/解释器自动优化它会很棒。
      • @terrinecold 等等,您链接中发布的方法与我链接到的比较中的方法相同,而且并不总是更快。我想它可能适用于更大的数组。
      【解决方案9】:
      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;     
      }
      

      【讨论】:

      • 对于array_unique 的实现不是很好,因为您依赖它作为数值。即使是唯一的数字数组,我认为 parseInt 会是更好的选择(我可能是错的)
      【解决方案10】:

      这会奏效。试试看。

      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;
      }
      

      【讨论】:

        【解决方案11】:

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

        Array.prototype.unique =
        function()
        {
            return this.filter(
                function(val, i, arr)
                {
                    return (i <= arr.indexOf(val));
                }
            );
        }
        

        【讨论】:

          【解决方案12】:

          没有多余的“返回”数组,没有 ECMA5(我很确定!)并且易于阅读。

          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;
          }
          

          【讨论】:

            【解决方案13】:

            这是您可以从 数组中删除重复值的方法。

            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;
                }
            }
            

            【讨论】:

              【解决方案14】:

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

              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”]

              【讨论】:

              • 当然,这只适用于字符串。
              • ……结果不应该包含初始数组的属性名称,而是实际的项目。预期:['0', '1', '2', '3']
              【解决方案15】:

              使用 google 闭包库的人可以使用 goog.array.removeDuplicates,这与 unique 相同。不过,它会更改数组本身。

              【讨论】:

                【解决方案16】:
                    //
                    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;
                      }
                    );
                    //
                

                【讨论】:

                  【解决方案17】:
                  Array.prototype.unique =function(){
                      var uniqObj={};
                      for(var i=0;i< this.length;i++){
                        uniqObj[this[i]]=this[i]; 
                      }
                      return uniqObj;
                  }
                  

                  【讨论】:

                  • 如果您对此进行了测试,甚至给出了一个测试示例,您会看到它返回的是一个对象,而不是用户要求的输出。请下次测试您的代码。
                  猜你喜欢
                  • 1970-01-01
                  • 2023-03-21
                  • 2012-06-30
                  • 1970-01-01
                  • 2010-12-29
                  相关资源
                  最近更新 更多