Javascript 排序和删除列表重复项的最有效算法?

Javascript 排序和删除列表重复项的最有效算法?,javascript,arrays,algorithm,sorting,Javascript,Arrays,Algorithm,Sorting,假设我有这样一个列表: [ 2, 7, 2, 3, 1, 1, 4, 5, 3, 6, 4 ] 我想对重复项进行排序和删除,以产生: [ 1, 2, 3, 4, 5, 6, 7 ] 我可以通过删除重复项然后进行排序来实现这一点: const uniqueAndSorted = xs => [ ...new Set(xs) ].sort(); 然而,这似乎效率低下,因为我可能在排序时检测到重复项 从列表中排序和删除重复项的最佳方法是什么? (JavaScript实现是首选;函数应该是非

假设我有这样一个列表:

[ 2, 7, 2, 3, 1, 1, 4, 5, 3, 6, 4 ]
我想对重复项进行排序和删除,以产生:

[ 1, 2, 3, 4, 5, 6, 7 ]
我可以通过删除重复项然后进行排序来实现这一点:

const uniqueAndSorted = xs => [ ...new Set(xs) ].sort();
然而,这似乎效率低下,因为我可能在排序时检测到重复项

从列表中排序和删除重复项的最佳方法是什么?


(JavaScript实现是首选;函数应该是非破坏性的)

我不确定这是否适用于所有浏览器,但您可以执行以下操作:

至少在Chrome中,它可以工作:

function getSortedSetArray(arr) {
  var map = {};

  arr.forEach(function (elem) {
    map[elem] = true;
  })

  return Object.keys(map);
} 

这是可行的,但最好采用以下几种方法进行基准测试:

function uniq_sort(a) {
    var seen = {};
    return a.filter(function(item) {
        return seen.hasOwnProperty(item) ? false : (seen[item] = true);
    }).sort();
}

您可以通过ES6设置来实现这一点

例如:

const uniqueAndSorted = xs => Array.from(new Set(xs)).sort();

uniqueAndSorted([2,7,2,3,1,1,4,5,3,6,4])
应该返回
[1,2,3,4,5,6,7]
这取决于您拥有的副本数量。如果重复项很少,那么先排序然后删除会更快。另一方面,如果有很多重复项,那么首先创建一个哈希集,然后排序是最好的选择

资料来源:

另一种选择是使用“fat pivot快速排序”或“三元分割快速排序”,当输入有许多重复项时,该方法比快速排序更快:


你说的非破坏性是什么意思?您是否希望保留原始数组而不重复并进行排序?您给定的代码与此不匹配。不应更改输入数组(
xs
),也就是说,如果可能,请将尽可能多的工作留给引擎。如果两者都有可能的话,使用库存函数和使用低级语言通常比用高级语言编写自定义算法要好——可读性和性能都更好。我会考虑你的
uniqueAndSorted
而不是在一周中的任何一天用JavaScript编写一个自定义的“同时做两件事”。@algrid“我认为你没有比过滤和排序更好的了。”这取决于你如何定义“更好”。过滤和排序需要你分配一个字典。但是如果你排序,然后过滤,你可以不用字典。实际上,哪个更快取决于重复的百分比。如果有很多(但我不知道“很多”是指2倍还是10倍)重复,那么首先过滤可能会更快。你真的想要“最有效”的方法吗?你如何定义效率?速度内存使用情况?你会选择一种简单、直接的方法,还是选择一种非常复杂和脆弱的解决方案,如果它能为你节省几微秒的时间?数组中有多少项?专注于做一些有用的东西。不要担心速度,除非你的速度太慢。你得到的是字符串而不是数字。没错,也不能保证它是排序的。对于正32位数字,键是排序的。哦,很高兴知道!这与问题中的示例有什么不同?一些字母和单词是不同的:)使用扩展运算符:const uniqueAndSorted=xs=>[…new Set(xs)].sort();
const uniqueAndSorted = xs => Array.from(new Set(xs)).sort();