如何获取数组中的唯一值

IT技术 javascript jquery
2021-01-16 05:24:57

如何获取数组中唯一值的列表?我是否总是必须使用第二个数组,或者是否有类似于 JavaScript 中 java 的 hashmap 的东西?

我将只使用JavaScriptjQuery不能使用额外的库。

6个回答

这是一个更简洁的 ES6 解决方案,我看到这里没有包含。它使用Set扩展运算符...

var a = [1, 1, 2];

[... new Set(a)]

哪个返回 [1, 2]

真是太聪明了!
2021-03-13 05:24:57
在 Typescript 中,您必须使用,Array.from(new Set(a))因为 Set 不能隐式转换为数组类型。只是抬头!
2021-03-23 05:24:57
现在,是一个单线!
2021-04-01 05:24:57

或者对于那些正在寻找与当前浏览器兼容的单线(简单和功能)的人

let a = ["1", "1", "2", "3", "3", "1"];
let unique = a.filter((item, i, ar) => ar.indexOf(item) === i);
console.log(unique);

2021 年更新 我建议查看Charles Clayton 的答案,由于最近对 JS 的更改,有更简洁的方法可以做到这一点。

更新 18-04-2017

似乎“Array.prototype.includes”现在在最新版本的主线浏览器中得到了广泛的支持(兼容性

2015 年 7 月 29 日更新:

有计划让浏览器支持标准化的“Array.prototype.includes”方法,虽然它没有直接回答这个问题;往往是相关的。

用法:

["1", "1", "2", "3", "3", "1"].includes("2");     // true

Pollyfill(浏览器支持来自 mozilla):

// https://tc39.github.io/ecma262/#sec-array.prototype.includes
if (!Array.prototype.includes) {
  Object.defineProperty(Array.prototype, 'includes', {
    value: function(searchElement, fromIndex) {

      // 1. Let O be ? ToObject(this value).
      if (this == null) {
        throw new TypeError('"this" is null or not defined');
      }

      var o = Object(this);

      // 2. Let len be ? ToLength(? Get(O, "length")).
      var len = o.length >>> 0;

      // 3. If len is 0, return false.
      if (len === 0) {
        return false;
      }

      // 4. Let n be ? ToInteger(fromIndex).
      //    (If fromIndex is undefined, this step produces the value 0.)
      var n = fromIndex | 0;

      // 5. If n ≥ 0, then
      //  a. Let k be n.
      // 6. Else n < 0,
      //  a. Let k be len + n.
      //  b. If k < 0, let k be 0.
      var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);

      // 7. Repeat, while k < len
      while (k < len) {
        // a. Let elementK be the result of ? Get(O, ! ToString(k)).
        // b. If SameValueZero(searchElement, elementK) is true, return true.
        // c. Increase k by 1.
        // NOTE: === provides the correct "SameValueZero" comparison needed here.
        if (o[k] === searchElement) {
          return true;
        }
        k++;
      }

      // 8. Return false
      return false;
    }
  });
}
它几乎是从 kennebec 复制粘贴的,但无可否认,将数组作为参数传递而不是使用闭包可能会提高性能。
2021-03-13 05:24:57
@GerardONeill 是的,在某些情况下它非常重要,例如,如果它在功能上被链接并且您想要访问尚未分配变量的数组,例如 .map(...).filter(...)
2021-03-14 05:24:57
很好——没有意识到过滤器作为参数在数组中发送,并且不想处理外部对象。这正是我所需要的——我的 javascript 版本(较旧的 xerces 版本)在一段时间内不会有新的好东西。
2021-03-19 05:24:57
- 必须说我没有连接点,只是扫描了一个衬里,看起来像一个大帖子,所以跳过了,去寻找替代来源并重新发布以供其他人快速找到。也就是说,你的权利;几乎和肯尼贝克一样。
2021-03-24 05:24:57
可怕的答案。O(N^2) 复杂度。不要使用这个。
2021-03-31 05:24:57

由于我在@Rocket 的回答的评论中继续讨论它,我不妨提供一个不使用库的示例。这需要两个新的原型函数,contains以及unique

Array.prototype.contains = function(v) {
  for (var i = 0; i < this.length; i++) {
    if (this[i] === v) return true;
  }
  return false;
};

Array.prototype.unique = function() {
  var arr = [];
  for (var i = 0; i < this.length; i++) {
    if (!arr.contains(this[i])) {
      arr.push(this[i]);
    }
  }
  return arr;
}

var duplicates = [1, 3, 4, 2, 1, 2, 3, 8];
var uniques = duplicates.unique(); // result = [1,3,4,2,8]

console.log(uniques);

为了获得更高的可靠性,您可以contains用 MDN 的indexOfshim替换并检查每个元素indexOf是否等于 -1:文档

这是一个非常低效的实现。检查结果数组以查看它是否已经包含一个项目是可怕的。更好的方法是使用跟踪计数的对象,或者如果您不想使用辅助存储,请先在 O(n log n) 中对其进行排序,然后进行线性扫描并并排比较元素
2021-03-11 05:24:57
谢谢你的例子。我将使用它们来过滤选择框的选项。这应该很好用。
2021-03-19 05:24:57
Array.from(new Set(arr))巨大的更快:jsperf.com/unique-func-vs-set/1 -说句公道话,这可能是当它被写了一个很好的答案,但你不应该现在使用它。
2021-03-20 05:24:57
我们真的需要“包含”功能吗?
2021-04-01 05:24:57
这具有很高的运行时间复杂度(最坏情况: O(n^2) )
2021-04-05 05:24:57

单行,纯 JavaScript

使用 ES6 语法

list = list.filter((x, i, a) => a.indexOf(x) === i)

x --> item in array
i --> index of item
a --> array reference, (in this case "list")

在此处输入图片说明

使用 ES5 语法

list = list.filter(function (x, i, a) { 
    return a.indexOf(x) === i; 
});

浏览器兼容性:IE9+

@AlexOkrushko 很公平 - 由于格式化方式而错过了该答案
2021-03-11 05:24:57
如果您将所有内容都放在一行上,那么一切都是单行的 :-)
2021-03-14 05:24:57
@Larry 这被否决了,因为在此之前几年提供了完全相同的答案。
2021-03-22 05:24:57
不知道为什么这被否决了。起初它可能有点晦涩难懂,也许被归类为“聪明”且不实用,但它具有声明性、非破坏性和简洁性,这是大多数其他答案所缺乏的。
2021-03-25 05:24:57
收紧a.indexOf(x) === i三个等号的相等注释可能会很好
2021-04-08 05:24:57

使用 EcmaScript 2016,您可以简单地这样做。

 var arr = ["a", "a", "b"];
 var uniqueArray = Array.from(new Set(arr)); // Unique Array ['a', 'b'];

集合总是唯一的,使用Array.from()您可以将集合转换为数组。作为参考,请查看文档。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/来自 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects /放

@Timmmm:哪些传播答案不适用于大型阵列?
2021-03-11 05:24:57
其实我觉得我错了。我在想什么时候人们会做类似的事情,Math.max(...foo)但是在数组中就可以了。indexOf尽管如此,这仍然是一个可怕的想法!
2021-03-30 05:24:57
这是您应该使用的答案。indexOf()答案很糟糕,因为它们是 O(N^2)。传播答案是可以的,但不适用于大型阵列。这是最好的方法。
2021-04-03 05:24:57