new Set(['b', 'a', 'c']).sort()
throws TypeError: set.sort is not a function
. How can I sort a Set
to ensure a particular iteration order?

- 24,913
- 29
- 97
- 127
-
11Sets are unordered. – SLaks Oct 12 '15 at 20:34
-
5@SLaks perhaps they are, but I'd like to be able to take advantage of the benefit of unique keys that `Set`s offer, while still being able to sort the elements. Java offers [`SortedSet`s](http://docs.oracle.com/javase/7/docs/api/java/util/SortedSet.html), I can only assume they did so because someone offered a valid use case... ES6 should not be Java, but sorting sets seems useful. – ericsoco Oct 12 '15 at 20:37
-
1You can't `sort()` a `SortedSet` either. It uses a tree structure that allows in-order traversal, but you cannot *change* this ordering as with an `ArrayList`. If you want to change the order, use lists. – Has QUIT--Anony-Mousse Oct 12 '15 at 22:54
-
1might need some research, but I think `Set` preserves order `new Set(['b', 'a', 'c'].sort())` – Slai Jul 29 '18 at 15:16
-
@Slai https://www.ecma-international.org/ecma-262/9.0/index.html#sec-set-objects I can not find any statement about the order of elements. – ceving Feb 25 '19 at 15:15
-
You can iterate through the elements of a set in insertion order. – Wojciech Bednarski Jul 25 '19 at 16:18
-
You’ve probably go the message that a set is a mathematical collection whose elements are unique and unordered. That JavaScript retains insertion order is an added feature. I guess the idea is that an Array is already ordered, so why would you order a set as well? In any case, you can construct the set by ordering the array first: `new Set(['b', 'a', 'c'].sort())` . – Manngo Oct 18 '19 at 05:56
-
See also the TC39 official discussion https://github.com/tc39/proposal-collection-methods/issues/12 – Yves M. May 27 '22 at 17:32
4 Answers
A set is not an ordered abstract data structure.
A Set
however always has the same iteration order - element insertion order [1], so when you iterate it (by an iterating method, by calling Symbol.iterator
, or by a for.. of loop) you can always expect that.
You can always convert the set to an array and sort that.
Array.from(new Set(["b","a","c"])).sort();
[...(new Set(["b","a","c"]))].sort(); // with spread.
[1] forEach
and CreateSetIterator

- 270,886
- 87
- 504
- 504
-
2Deleted my own answer that is the same as this, but will add back my comment: "I'm really hoping someone can provide an answer that doesn't require going from `Set` to `Array` and back. Seems pretty inefficient." – ericsoco Oct 12 '15 at 20:38
-
15@ericsoco the ECMAScript spec does not specify an `OrderedSet` but a similar data structure exists in multiple other languages - typically implemented by a tree. You can use a userland collections library, namely - the popular ImmutableJS provides an [`OrderedSet`](https://facebook.github.io/immutable-js/docs/#/OrderedSet). Indeed that will likely be more efficient in a lot of cases. So if you have a set with over 100K elements - I'd definitely consider using an ordered set implementation instead. – Benjamin Gruenbaum Oct 12 '15 at 20:40
-
9Please note that for set of numbers you have to give sort a comparison function: `(x, y) => x - y`. Your numbers will be sorted lexicographically otherwise. – neo Oct 09 '16 at 17:01
-
2@BenjaminGruenbaum: I think you've misunderstood something; according to its documentation, Immutable.js's `OrderedSet` uses the *insertion order* as the iteration order; that is, it does the same thing that, according to your answer, the standard `Set` does. – ruakh Apr 02 '19 at 20:03
-
3@ruakh However, an ImmutableJS `OrderedSet` object *does* allow you to sort() its contents, which a) the standard `Set` *does not*, and b) is the functionality OP wanted. – Jamie Ridding May 23 '20 at 02:20
-
1
-
@ruakh, yeah you're right, might as well use the regular `Set` from immutable.js, which also provides a sort function: https://immutable-js.com/docs/v4.3.0/Set/#sort() – MazeChaZer Jul 24 '23 at 13:43
In some cases it may be preferable to "sort" the set in-place, similar to array.sort()
, it can be done like this:
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,296
- 29
- 31
the simplest way to do it as.
console.log(new Set(['b', 'a', 'c'].sort()))
//Set(3) {"a", "b", "c"}

- 620
- 4
- 14
-
according to the question, his target was to retain the order of iteration in the set. it's not necessary to sort items in Set. – Taimoor Qureshi Sep 21 '21 at 15:16
The .sort function is a higher order function which means it can have another function inside. First of all only .sort() may work with characters or strings but it will give bugs for numbers. I have discussed sets in my video along with sort function. I hope you understand it. https://www.youtube.com/watch?v=ztw4Gh8eogw
//This is sort() for getting numbers in ascending order:
const setC = new Set(([58,12,11,10,5,32]).sort((a,b)=>a -b));
//This is sort() for getting numbers in descending order:
const setC = new Set(([58,12,11,10,5,32]).sort((a,b)=>b -a));
//This is sort() for strings
const setD=new Set((['mangoes','bananas', 'apples','oranages']).sort());
// This is sort() for characters
const setD=new Set((['m', 'b', 'a', 'r']).sort());
You can convert the set to an array too and then sort it but that is not
required in your case.
const arrayofsetA = Array.from(setA);
//for strings or characters
arrayofsetA.sort();
//for numbers or floating point numbers
arrayofsetA.sort((a,b) => a-b);

- 115
- 1
- 10