如何对 ES6 `Set` 进行排序?

Posted

技术标签:

【中文标题】如何对 ES6 `Set` 进行排序?【英文标题】:How can I sort an ES6 `Set`? 【发布时间】:2016-01-10 10:30:52 【问题描述】:

new Set(['b', 'a', 'c']).sort() 抛出 TypeError: set.sort is not a function。如何对Set 进行排序以确保特定的迭代顺序?

【问题讨论】:

集合是无序的。 @SLaks 也许是这样,但我希望能够利用Sets 提供的唯一键的好处,同时仍然能够对元素进行排序。 Java 提供SortedSets,我只能假设他们这样做是因为有人提供了一个有效的用例...... ES6 不应该是 Java,但排序集似乎很有用。 你也不能sort()SortedSet。它使用允许按顺序遍历的树结构,但您不能像使用ArrayList 那样更改此顺序。如果要更改顺序,请使用列表。 可能需要一些研究,但我认为Set 保留了订单new Set(['b', 'a', 'c'].sort()) @Slai ecma-international.org/ecma-262/9.0/index.html#sec-set-objects我找不到关于元素顺序的任何声明。 【参考方案1】:

集合不是有序的抽象数据结构。

然而,Set 始终具有相同的迭代顺序 - 元素插入顺序 [1],因此当您迭代它时(通过迭代方法、通过调用 Symbol.iterator 或通过 for.. of 循环),您可以永远期待。

您始终可以将集合转换为数组并对其进行排序。

Array.from(new Set(["b","a","c"])).sort();
[...(new Set(["b","a","c"]))].sort(); // with spread.

[1] forEach 和 CreateSetIterator

【讨论】:

删除了与此相同的我自己的答案,但会添加我的评论:“我真的希望有人可以提供不需要从 Set 转到 @987654329 的答案@ 并返回。似乎效率很低。” @ericsoco ECMAScript 规范没有指定OrderedSet,但类似的数据结构存在于多种其他语言中——通常由树实现。您可以使用用户空间集合库,即 - 流行的 ImmutableJS 提供了一个OrderedSet。事实上,在很多情况下,这可能会更有效。因此,如果您有一个包含超过 100K 元素的集合 - 我肯定会考虑使用有序集合实现。 请注意,对于一组数字,您必须提供排序比较函数:(x, y) => x - y。否则,您的数字将按字典顺序排序。 @BenjaminGruenbaum:我认为你误解了一些东西;根据其文档,Immutable.js 的 OrderedSet 使用 插入顺序 作为迭代顺序;也就是说,根据您的回答,它的作用与标准 Set 的作用相同。 @ruakh 但是,ImmutableJS OrderedSet 对象允许 允许您对其内容进行排序(),而标准Set 不允许 i> 和 b) 是 OP 想要的功能。【参考方案2】:

在某些情况下,最好对集合进行就地“排序”,类似于array.sort(),可以这样完成:

function sortSet(set) 
  const entries = [];
  for (const member of set) 
    entries.push(member);
  
  set.clear();
  for (const entry of entries.sort()) 
    set.add(entry);
  
  return set;
;

sortSet(new Set([3,2,1]))
// => Set(3)  1, 2, 3 

【讨论】:

【参考方案3】:

最简单的方法。

console.log(new Set(['b', 'a', 'c'].sort()))
//Set(3) "a", "b", "c"

【讨论】:

根据问题,他的目标是保留集合中的迭代顺序。不需要对 Set 中的项目进行排序。

以上是关于如何对 ES6 `Set` 进行排序?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Vim 按字母顺序对 JS es6 导入进行排序

如何根据已排序索引的向量对 std::set 索引进行排序?

如何对List 进行排序

java 如何对对象进行排序

ES6 set方法对数组去重和排序

如何在 JavaScript 中按值对地图进行排序?