如何在 JavaScript 中创建唯一项目列表? [复制]

Posted

技术标签:

【中文标题】如何在 JavaScript 中创建唯一项目列表? [复制]【英文标题】:How to create a list of unique items in JavaScript? [duplicate] 【发布时间】:2012-07-26 04:25:37 【问题描述】:

在我的 CouchDB reduce 函数中,我需要将项目列表缩减为唯一的项目。

注意:在这种情况下,有一个列表是可以的,它将是字符串类型的少量项目。

我目前的方法是设置对象的键,然后返回该对象的键 因为代码不能使用_.uniq之类的地方。

我想找到一种比这个更优雅的拼写方式。

function(keys, values, rereduce) 
  // values is a Array of Arrays
  values = Array.concat.apply(null, values);
  var uniq = ;
  values.forEach(function(item)  uniq[item] = true; );
  return Object.keys(uniq);

【问题讨论】:

根据你定义的优雅,你可以在github上查找下划线的唯一来源 下划线仅用于字符串更昂贵,并且由于需要在一般情况下工作而不太优雅 你需要reduce函数吗?如果您只需要唯一值,您可以在请求视图时使用group=true 选项。有关这方面的更多信息,请参阅CouchDB Wiki 可能重复[获取数组中的所有唯一值(删除重复)***.com/questions/1960473/… 【参考方案1】:

最好的方法似乎是使用 ES6 和 Set。根据fiddle,单行且比上面更快*

    
const myList = [1,4,5,1,2,4,5,6,7];
const unique = [...new Set(myList)];
    
console.log(unique);

*在 Safari 中测试

【讨论】:

你也可以只做new Set([1,2,4,6]),这不那么难看 new Set(list) 只会创建一个 Set。 是的,你是对的,我的意思是Array.from(new Set([1,2,4,6])),看看我的回答【参考方案2】:

2021 年答案:

const unique = (arr) => [...new Set(arr)];
unique([1, 2, 2, 3, 4, 4, 5, 1]); // [1, 2, 3, 4, 5]

在这里,您只需从给定数组创建一个set,然后将其转换回数组。 我测量了性能,现在它几乎比我之前发布的旧答案中提出的方法快两倍。而且,它只是一条线。

Updated fiddle

旧答案仅作记录:

通常,您使用的方法是个好主意。 但我可以提出一个解决方案,让算法更快。

function unique(arr) 
    var u = , a = [];
    for(var i = 0, l = arr.length; i < l; ++i)
        if(!u.hasOwnProperty(arr[i])) 
            a.push(arr[i]);
            u[arr[i]] = 1;
        
    
    return a;

如您所见,我们这里只有一个循环。

我创建了一个example,用于测试您和我的解决方案。试着玩一下。

【讨论】:

在处理集合和循环时,算法的速度总是很重要的。 如果我使用for(var i=0; i&lt;arr.length; ++i),它会在每个循环中重新计算数组的长度吗?或者为什么要创建一个单独的l 变量? @MarkusMeskanen 这取决于特定的 javascript 引擎实现。另外,不要忘记属性查找时间。 今天通过 chrome 打开测试链接显示测试速度几乎没有差异。这个答案是最新的还是浏览器优化了性能差异?我已经更新了 jsfiddle 以及我的 indexOf 命题。 @FélixAdriyelGagnon-Grenier 奇怪。我仍然在 Linux Chrome 中获得了大约 0.7-0.8 的比率。但有时它> 1。所以看起来 ES 引擎现在以不同的方式工作。【参考方案3】:

适用于小型列表的替代方法是模仿sort | uniq 的 Unix 命令行方法:

    function unique(a) 
        return a.sort().filter(function(value, index, array) 
            return (index === 0) || (value !== array[index-1]);
        );
    

此函数对参数进行排序,然后过滤结果以省略任何与其前任相同的项目。

基于键的方法很好,并且对于大量项目(将 n 个项目插入哈希表的 O(n) 与对数组排序的 O(n log n) 相比)具有更好的性能特征。但是,这在小型列表中不太可能引起注意。此外,在此版本中,您可以根据需要修改它以使用不同的排序或相等函数;使用哈希键时,您会被 JavaScript 的键相等概念所困扰。

【讨论】:

漂亮,能够在 ember.js 中使用它来使用 Arrayproxy 的“过滤器”功能过滤记录数组【参考方案4】:

这应该适用于任何东西,而不仅仅是字符串:

export const getUniqueList =  (a: Array<any>) : Array<any> => 

  const set = new Set<any>();

  for(let v of a)
      set.add(v);
  

  return Array.from(set);

;

以上可以简化为:

export const getUniqueValues = (a: Array<any>) => 
   return Array.from(new Set(a));
;

:)

【讨论】:

【参考方案5】:

如果你输入整数参数,使用 Object.keys 会给你字符串 (uniq([1,2,3]) => ['1','2','3']。这里是 Array.reduce :

function uniq(list) 
    return list.reduce((acc, d) => acc.includes(d) ? acc : acc.concat(d), []);

【讨论】:

【参考方案6】:

这是一个老问题,我知道。但是,它位于一些谷歌搜索的顶部,所以我想补充一点,您可以使用以下方法组合来自 @RobHague 和 @EugeneNaydenov 的答案:

function unique(arr) 
  const u = ;
  return arr.filter((v) => 
    return u[v] = !u.hasOwnProperty(v);
  );
;

您也可以通过添加以下内容来忽略 undefined 值(通常很方便):

function unique(arr) 
  const u = ;
  return arr.filter((v) => 
    return u[v] = (v !== undefined && !u.hasOwnProperty(v));
  );
;

您可以在此处使用此解决方案:https://jsfiddle.net/s8d14v5n/

【讨论】:

或许可以使用new Set 来获得更多乐趣【参考方案7】:

我发现其他答案相当复杂,我看不到任何收获。

我们可以使用Array的indexOf方法在push之前验证其中是否存在item:

const duplicated_values = ['one', 'one', 'one', 'one', 'two', 'three', 'three', 'four'];
const unique_list = [];

duplicated_values.forEach(value => 
  if (unique_list.indexOf(value) === -1) 
    unique_list.push(value);
  
);

console.log(unique_list);

这也适用于任何类型的变量,甚至对象(假设标识符实际上引用了相同的实体,只是等效的对象不被视为相同)。

【讨论】:

【参考方案8】:

要获取唯一对象,可以使用JSON.stringifyJSON.parse

const arr = [test: "a", test: "a"];
const unique = Array.from(new Set(arr.map(JSON.stringify))).map(JSON.parse);
console.log(unique);

【讨论】:

【参考方案9】:

怎么样

    function unique(list) 
      for (i = 0; i<list.length; i++) 
        for (j=i+1; j<list.length; j++) 
          if (list[i] == list[j]) 
            list.splice(j, 1);
          
        
      
    

【讨论】:

运行list.splice()后需要将j递减。这种 O(N^2) 解决方案适用于小型数组,但一旦数组变大我就不会使用它。

以上是关于如何在 JavaScript 中创建唯一项目列表? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 HTML/Javascript 中创建可编辑的组合框?

如何从列表中创建唯一的非重复对组合

如何在 javascript 中创建一个单词的所有可能字谜的列表?

在 JavaScript 中创建全局唯一 ID [重复]

如何使用 bit 在 javascript 项目中创建 typescript 组件?

如何在 JavaScript/TypeScript 中创建具有非唯一键的地图?