iterator.toArray() walks the whole iterator and allocates an array. The array is wasted if the next step takes any iterable, or calls a method that iterators have too.
The rule reports .toArray():
- in
for...of,yield*and a spread into an array or a call - as the argument of
new Set(),new Map(),new WeakSet(),new WeakMap()or a typed array constructor - as the argument of
Array.from(),Object.fromEntries(),Promise.all(),Promise.allSettled(),Promise.any()orPromise.race() - before
.every(),.find(),.forEach(),.some()or.reduce()with an initial value
--fix removes the .toArray(). Before an iterator method and in the Promise methods, only --fix-suggestions does.
Configure
Off by default. To turn it on:
[lint.rules]
"unicorn/no-useless-iterator-to-array" = "error" # or "warn"
Examples
Reported:
for (const name of users.keys().toArray()) {
console.log(name);
}
const ids = new Set(users.values().map(user => user.id).toArray());
const list = [...users.values().toArray()];
const hasAdmin = users.values().toArray().some(user => user.admin);
Not reported:
for (const name of users.keys()) {
console.log(name);
}
const ids = new Set(users.values().map(user => user.id));
const list = [...users.values()];
const hasAdmin = users.values().some(user => user.admin);
Methods that only arrays have still need the array, and so does a callback that takes the array as its third parameter:
const sorted = users.values().toArray().sort(byName);
const isUnique = users.values().toArray().every((user, index, all) => all.indexOf(user) === index);
When not to use it
The rule can't see types, so it reports every .toArray() call without arguments in these places. Turn it off if you use a library with its own toArray() on objects that aren't iterable.