JavaScript Array
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
https://devdocs.io/javascript-array/
https://github.com/tc39/proposal-change-array-by-copy → Adds toReversed()
, toSorted(compareFn)
, toSpliced(start, deleteCount, ...items)
and with(index, value)
.
Mutation
https://lorenstewart.me/2017/01/22/javascript-array-methods-mutating-vs-non-mutating/
Immutability isn't free: https://swizec.com/blog/immutability-isnt-free/
For the inner loop we replaced array spread for each group of slots with an array.push, which mutates an array in-place. Becoming an O(1) operation.
Instead of creating a new copy of the whole array on every iteration, we push data to the result array in-place. Turning an O(n^2) reduce statement into O(n).
Array.isArray()
Array.isArray([]) // true
Array.isArray('a') // false
Get the first N elements
items.slice(0, MAX_COUNT)
Does not mutate. MDN
Remove duplicate values from array / get unique values from array
- https://stackoverflow.com/questions/9229645/remove-duplicate-values-from-js-array
- https://stackoverflow.com/questions/1960473/get-all-unique-values-in-a-javascript-array-remove-duplicates
const uniq = [...new Set(array)]
In https://docs.astro.build/en/tutorial/5-astro-api/2/ they use this to get all tags from an array of blog posts (where each post can have multiple tags):
const uniqueTags = [...new Set(posts.map((post) => post.tags).flat())]
Sort (eg by date)
Mutates
export interface Item {
date: number // time in millis, eg 1622451442822
}
function sortByDate(a: Item, b: Item): number {
return a.date - b.date // oldest first
return b.date - a.date // newest first
}
items.sort(sortByDate)
Delete an item with items.splice(index, 1)
Mutates
We need the index of the item. If we have the item, use indexOf
: items.splice(items.indexOf(item), 1)
.
Otherwise, use findIndex
to find the index:
const index = items.findIndex((item) => item.id === id)
if (index !== -1) {
items.splice(index, 1)
}
at()
When using 0 or positive integers, it does not offer any advantage over the square bracket notation. The only difference is that at()
supports negative integers.
const items = ['a', 'b', 'c']
items.at(-1) // 'c'
items[-1] // undefined
items.at(-2) // 'b'
items[-2] // undefined
So instead of doing items[items.length - 1]
we can just do items.at(-1)
.
every()
[1, 2].every(i => i > 0) // true
[-1, 2].every(i => i > 0) // false
find()
Returns the first element that satisfies the predicate or undefined
.
['a', 'b'].find(i => i.length > 0) // 'a'
['a', 'b'].find(i => i.length > 10) // undefined
findLast()
starts by the end:
['a', 'b'].findLast(i => i.length > 0) // 'b'
['a', 'b'].findLast(i => i.length > 10) // undefined
findIndex()
Returns the index of the first element that satisfies the predicate or -1.
['a', 'b'].findIndex(i => i.length > 0) // 0
['a', 'b'].findIndex(i => i.length > 10) // -1
findLastIndex()
starts by the end:
['a', 'b'].findLastIndex(i => i.length > 0) // 1
['a', 'b'].findLastIndex(i => i.length > 10) // -1
includes()
[1, 2].includes(2) // true
[1, 2].includes(3) // false
indexOf()
A simpler way to do ['a', 'b'].findIndex(i => i === 'a')
. It takes an item instead of a function.
['a', 'b'].indexOf('a') // 0
['a', 'b'].indexOf('c') // -1
some()
[1, 2].some(i => i > 0) // true
[-1, 2].some(i => i > 0) // true
[-1, -2].some(i => i > 0) // false