lodashより小サイズで2〜3倍高速なes-toolkitの使い方

es-toolkitとは

es-toolkitはモダンなJavaScriptユーティリティライブラリで、lodashのような関数を提供します。

lodashと比較して、es-toolkitは大幅に小さいバンドルサイズ(最大97%減)と2〜3倍高速なランタイムパフォーマンスを提供します。

これは最新のJavaScript機能を活用したモダンな実装によって実現されています。

さらにes-toolkitにはTypeScriptの型が組み込まれており、100%のテストカバレッジを保証する厳密なテストが行われ、最大の信頼性を実現しています。

Node.js、Deno、Bun、ブラウザを含むすべてのJavaScript環境をサポートしているため、最近の開発環境を使用しているのであればlodashよりもes-toolkitのほうが相性が良いです。

es-toolkitのインストール

以下のコマンドでインストールします。

npm i -D es-toolkit

es-toolkitの機能

以下はes-toolkitが提供する機能の一部です。

Arrayuniqやdifferenceなどの配列操作ユーティリティ
Functiondebounceやthrottleなどのツール
Mathsumやroundなどの数値演算ユーティリティ
Objectpickやomitなどのツール
PredicateisNotNilのようなタイプガード関数
Promisedelayのような非同期ユーティリティ
StringsnakeCaseのような文字列操作用ユーティリティ

例えば、Arrayのchunkを使用する場合は以下のように 'es-toolkit/array' からインポートして利用します。

TypeScript
import { chunk } from 'es-toolkit/array'

Arrayのリファレンス

chunk

配列を指定した長さの小さな配列に分割します。

TypeScript
import { chunk } from 'es-toolkit/array'

const result = chunk([1, 2, 3, 4, 5], 2)
console.log(result)
// [[1, 2], [3, 4], [5]]

countBy

配列内の各項目の出現回数を数えてオブジェクトで返します。

TypeScript
import { countBy } from 'es-toolkit/array'

const array = [1, 2, 3, 4, 5]
const result = countBy(array, x => x % 2 === 0 ? 'even' : 'odd')

console.log(result)
// { 'odd': 3, 'even': 2 }

compact

false、null、0、''、undefined、NaNを配列から削除します。

TypeScript
import { compact } from 'es-toolkit/array'

const result = compact([1, false, 2, '', null, undefined, NaN, 3])
console.log(result)
// [1, 2, 3]

difference

1番目の配列から、2番目の配列の値と一致するものを取り除いて返します。

TypeScript
import { difference } from 'es-toolkit/array'

const array1 = [1, 2, 3, 4]
const array2 = [2, 4, 5]
const result = difference(array1, array2)
console.log(result)
// [1, 3]

differenceBy

指定された関数で要素をマッピングした後、2 つの配列の差を返します。

TypeScript
import { differenceBy } from 'es-toolkit/array'

type Item = { id: number }

const array1 = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }]
const array2 = [{ id: 2 }, { id: 4 }]
const mapper = (item: Item) => item.id
const result = differenceBy(array1, array2, mapper)
console.log(result)
// [{ id: 1 }, { id: 3 }]

differenceWith

カスタム等号関数に基づいて、2つの配列の差を返します。

TypeScript
import { differenceWith } from 'es-toolkit/array'

type Item = { id: number }

const array1 = [{ id: 1 }, { id: 2 }, { id: 3 }]
const array2 = [{ id: 2 }, { id: 4 }, { id: 5 }]
const arrItemsEqual = (a: Item, b: Item) => a.id === b.id
const result = differenceWith(array1, array2, arrItemsEqual)
console.log(result)
// [{ id: 1 }, { id: 3 }]

drop

配列の先頭から指定した数の要素を取り除いて返します。

TypeScript
import { drop } from 'es-toolkit/array'

const array = [1, 2, 3, 4, 5]
const result = drop(array, 2)
console.log(result)
// [3, 4, 5]

dropWhile

falseを返すまで、配列の先頭から要素を削除します。

TypeScript
import { dropWhile } from 'es-toolkit/array'

const array = [1, 2, 4, 3, 5, 6]
const result = dropWhile(array, x => x < 3)
console.log(result)
// [4, 3, 5, 6]

dropRight

配列の末尾から指定した数の要素を削除して、残りを返します。

TypeScript
import { dropRight } from 'es-toolkit/array'

const array = [1, 2, 3, 4, 5]
const result = dropRight(array, 2)
console.log(result)
// [1, 2, 3]

dropRightWhile

falseを返すまで、配列の末尾から要素を削除します。

TypeScript
import { dropRightWhile } from 'es-toolkit/array'

const array = [1, 2, 4, 3, 5, 6]
const result = dropRightWhile(array, x => x > 3)
console.log(result)
// [1, 2, 4, 3]

fill

配列の要素を開始位置から終了位置までを指定された値で埋めます。

TypeScript
import { fill } from 'es-toolkit/array'

const array1 = [1, 2, 3]
const result1 = fill(array1, 'a')
console.log(result1)
// ['a', 'a', 'a']

const array2 = Array(3)
const result2 = fill(array2, 2)
console.log(result2)
// [2, 2, 2]

const array3 = [4, 6, 8, 10]
const result3 = fill(array3, '*', 1, 3)
console.log(result3)
// [4, '*', '*', 10]

const creditNumber = '1234567899990000'
const result4 = fill(creditNumber.split(''), '*', 0, creditNumber.length - 4).join('')
console.log(result4)
// ************0000

toFilled

開始位置から終了位置までの、指定した値で満たされた新しい配列を作成します。

バージョン1.9.0では使用不可。

TypeScript
import { toFilled } from 'es-toolkit/array'

const array = [1, 2, 3, 4, 5]
let result = toFilled(array, '*', 2)
console.log(result)
// [1, 2, '*', '*', '*']

result = toFilled(array, '*', 1, 4)
console.log(result)
// [1, '*', '*', '*', 5]

result = toFilled(array, '*')
console.log(result)
// ['*', '*', '*', '*', '*']

result = toFilled(array, '*', -4, -1)
console.log(result)
// [1, '*', '*', '*', 5]

console.log(array)
// [1, 2, 3, 4, 5]

flatten

第1引数として与えられた入れ子の配列を必要な深さにフラットにします。

第2引数にフラットにする深さを数値で指定します。(省略するとデフォルトの1になる)

TypeScript
import { flatten } from 'es-toolkit/array'

const array1 = [1, [2, 3], [4, [5, 6]]]
const result1 = flatten(array1, 1)
console.log(result1)
// [1, 2, 3, 4, [5, 6]]

const array2 = [1, [2, 3], [4, [5, [6]]]]
const result2 = flatten(array2, Infinity)
console.log(result2)
// [1, 2, 3, 4, 5, 6]

flattenDeep

入れ子配列のすべての深さをフラットにします。

バージョン1.9.0では使用不可。

TypeScript
import { flattenDeep } from 'es-toolkit/array'

const array = [1, [2, 3], [4, [5, 6]]]
const result = flattenDeep(array, 1)
console.log(result)
// [// [1, 2, 3, 4, 5, 6]

forEachRight

arrの要素を右から左に反復処理し、各要素に対してコールバックを呼び出します。

TypeScript
import { forEachRight } from 'es-toolkit/array'

const array = [1, 2, 3]
const result: number[] = []

forEachRight(array,  (value) => {
  result.push(value * 10)
})
console.log(result)
// [30, 20, 10]

groupBy

指定されたキー生成関数に基づいて配列の要素をグループ化します。

TypeScript
import { groupBy } from 'es-toolkit/array'

const array = [
  { category: 'fruit', name: 'apple' },
  { category: 'fruit', name: 'banana' },
  { category: 'vegetable', name: 'carrot' },
]
const result = groupBy(array, item => item.category)
console.log(result)
// {
//   fruit: [
//     { category: 'fruit', name: 'apple' },
//     { category: 'fruit', name: 'banana' }
//   ],
//   vegetable: [
//     { category: 'vegetable', name: 'carrot' }
//   ]
// }

intersection

2つの配列の交点を返します。

TypeScript
import { intersection } from 'es-toolkit/array'

const array1 = [1, 2, 3, 4, 5]
const array2 = [3, 4, 5, 6, 7]
const result = intersection(array1, array2)
console.log(result)
// [3, 4, 5]

intersectionBy

マッピング関数に基づいて2つの配列の交点を返します。

TypeScript
import { intersectionBy } from 'es-toolkit/array'

type Item = { id: number }

const array1 = [{ id: 1 }, { id: 2 }, { id: 3 }]
const array2 = [{ id: 2 }, { id: 4 }]
const mapper = (item: Item) => item.id
const result = intersectionBy(array1, array2, mapper)
console.log(result)
// [{ id: 2 }]

intersectionWith

カスタム等号関数を使用して、2つの配列の交点を返します。

TypeScript
import { intersectionWith } from 'es-toolkit/array'

type Item = { id: number }

const array1 = [{ id: 1 }, { id: 2 }, { id: 3 }]
const array2 = [{ id: 2 }, { id: 4 }]
const areItemsEqual = (a: Item, b: Item) => a.id === b.id
const result = intersectionWith(array1, array2, areItemsEqual)
console.log(result)
// [{ id: 2 }]

keyBy

配列の各要素を指定されたキー生成関数に基づいてマップします。

同じキーを生成する要素が複数ある場合は最後の要素が値として使用されます。

TypeScript
import { keyBy } from 'es-toolkit/array'

const array = [
  { category: 'fruit', name: 'apple' },
  { category: 'fruit', name: 'banana' },
  { category: 'vegetable', name: 'carrot' },
]
const result = keyBy(array, item => item.category)
console.log(result)
// {
//   fruit: { category: 'fruit', name: 'banana' },
//   vegetable: { category: 'vegetable', name: 'carrot' }
// }

minBy

指定したキーの最小値を持つ配列の要素を返します。

配列の要素が存在しない場合はundefinedを返します。

TypeScript
import { minBy } from 'es-toolkit/array'

const result = minBy([{ a: 1 }, { a: 2 }, { a: 3 }], x => x.a)
console.log(result)
// { a: 1 }

maxBy

指定したキーの最大値を持つ配列の要素を返します。

配列の要素が存在しない場合はundefinedを返します。

TypeScript
import { maxBy } from 'es-toolkit/array'

const result = maxBy([{ a: 1 }, { a: 2 }, { a: 3 }], x => x.a)
console.log(result)
// { a: 3 }

orderBy

複数のプロパティとそれに対応する順序方向に基づいて、オブジェクトの配列をソートします。

TypeScript
import { orderBy } from 'es-toolkit/array'

const users = [
  { user: 'fred', age: 48 },
  { user: 'barney', age: 34 },
  { user: 'fred', age: 40 },
  { user: 'barney', age: 36 },
]

const result = orderBy(users, ['user', 'age'], ['asc', 'desc'])
console.log(result)
// [
//   { user: 'barney', age: 36 },
//   { user: 'barney', age: 34 },
//   { user: 'fred', age: 48 },
//   { user: 'fred', age: 40 },
// ]

複数のプロパティではなく単数のプロパティの場合は、sort()を使用してください。

TypeScript
const users = [
  { user: 'fred', age: 48 },
  { user: 'barney', age: 34 },
  { user: 'fred', age: 40 },
  { user: 'barney', age: 36 },
]

const result = users.sort((a, b) => a.age - b.age)
console.log(result)
// [
//   { user: 'barney', age: 34 },
//   { user: 'barney', age: 36 },
//   { user: 'fred', age: 40 },
//   { user: 'fred', age: 48 }
// ]

partition

配列を2つの変数に分割します。

TypeScript
import { partition } from 'es-toolkit/array'

const array = [1, 2, 3, 4, 5]
const isEven = (x: number) => x % 2 === 0
const [even, odd] = partition(array, isEven)

console.log(even) // [2, 4]
console.log(odd)  // [1, 3, 5]

sample

配列からランダムな要素を返します。

TypeScript
import { sample } from 'es-toolkit/array'

const array = [1, 2, 3, 4, 5]
const result = sample(array)
console.log(result)
// 1〜5のいずれか

sampleSize

指定したサイズの要素配列をランダムで返します。

TypeScript
import { sampleSize } from 'es-toolkit/array'

const array = [1, 2, 3, 4, 5]
const result = sampleSize(array, 2)
console.log(result)
// 例: [4, 2]

shuffle

配列をシャッフルする。

TypeScript
import { shuffle } from 'es-toolkit/array'

const array = [1, 2, 3, 4, 5]
const result = shuffle(array)
console.log(result)
// 例: [5, 2, 1, 3, 4]

take

配列から最初の指定した個数の要素を含む新しい配列を返します。

TypeScript
import { take } from 'es-toolkit/array'

const array = [1, 2, 3, 4, 5]
const result = take(array, 3)
console.log(result)
// [1, 2, 3]

takeWhile

与えられた条件で配列の先頭の要素を含む新しい配列を返します。

条件を満たさない時点で、要素の取り込みを停止します。

TypeScript
import { takeWhile } from 'es-toolkit/array'

const array = [1, 2, 3, 4, 5]
const result = takeWhile(array, x => x < 3)
console.log(result)
// [1, 2]

takeRight

配列の要素数の最後の指定した個数を含む新しい配列を返します。

TypeScript
import { takeRight } from 'es-toolkit/array'

const array = [1, 2, 3, 4, 5]
const result = takeRight(array, 3)
console.log(result)
// [3, 4, 5]

takeRightWhile

与えられた条件で配列の最後の要素を含む新しい配列を返します。

条件を満たさない時点で、要素の取り込みを停止します。

TypeScript
import { takeRightWhile } from 'es-toolkit/array'

const array = [1, 2, 3, 4, 5]
const result = takeRightWhile(array, x => x > 3)
console.log(result)
// [4, 5]

union

与えられたすべての配列から一意な値の配列を作成します。

TypeScript
import { union } from 'es-toolkit/array'

const array1 = [1, 2, 3]
const array2 = [3, 4, 5]
const result = union(array1, array2)
console.log(result)
// [1, 2, 3, 4, 5]

unionBy

指定されたマッピング関数を使用して、指定されたすべての配列から一意な値の配列を順番に作成します。

TypeScript
import { unionBy } from 'es-toolkit/array'

const array1 = [{ id: 1 }, { id: 2 }]
const array2 = [{ id: 2 }, { id: 3 }]
const result = unionBy(array1, array2, x => x.id)
console.log(result)
// [{ id: 1 }, { id: 2 }, { id: 3 }]

unionWith

条件に基づき、与えられた二つの配列から一意な値の配列を作成します。

TypeScript
import { unionWith } from 'es-toolkit/array'

type Item = { id: number }

const array1 = [{ id: 1 }, { id: 2 }]
const array2 = [{ id: 2 }, { id: 3 }]
const arrItemsEqual = (a: Item, b: Item) => a.id === b.id
const result = unionWith(array1, array2, arrItemsEqual)
console.log(result)
// [{ id: 1 }, { id: 2 }, { id: 3 }]

uniq

重複のない配列を作成します。

TypeScript
import { uniq } from 'es-toolkit/array'

const array = [1, 2, 2, 3, 4, 4, 5]
const result = uniq(array)
console.log(result)
// [1, 2, 3, 4, 5]

uniqBy

mapper関数が返す値に基づいて、元の配列から一意な要素のみを含む新しい配列を返します。

以下の例では1.2と1.5はMath.floorでどちらも1なので、最初の1.2のほうが配列に残ります。

TypeScript
import { uniqBy } from 'es-toolkit/array'

const array = [1.2, 1.5, 2.1, 3.2, 5.7, 5.3, 7.19]
const result = uniqBy(array, Math.floor)
console.log(result)
// [1.2, 2.1, 3.2, 5.7, 7.19]

uniqWith

関数の条件によって返された値に基づいて、元の配列からユニークな要素のみを含む新しい配列を返します。

TypeScript
import { uniqWith } from 'es-toolkit/array'

const array = [1.2, 1.5, 2.1, 3.2, 5.7, 5.3, 7.19]
const result = uniqWith(array, (a, b) => Math.abs(a - b) < 1)
console.log(Math.abs(1.2))
console.log(result)
// [1.2, 3.2, 5.7, 7.19]

unzip

要素のグループ化された配列から、内部配列の同じ位置にある要素を集めて新しい配列として返します。

TypeScript
import { unzip } from 'es-toolkit/array'

const result = unzip([
  ['a', true, 1],
  ['b', false, 2],
])
console.log(result)
// [['a', 'b'], [true, false], [1, 2]]

unzipWith

配列を解凍し、再グループ化された要素にイテレート関数を適用する。

TypeScript
import { unzipWith } from 'es-toolkit/array'

const nestedArray = [
  [1, 2],
  [3, 4],
  [5, 6],
]
const result = unzipWith(nestedArray, (item, item2, item3) => {
  return item + item2 + item3
})
console.log(result)
// [9, 12]

without

指定したすべての値を除外する配列を作成します。

TypeScript
import { without } from 'es-toolkit/array'

const result = without([1, 2, 3, 4, 5], 2, 4)
console.log(result)
// [1, 3, 5]

xor

2つの配列の対称差分を計算して返します。

TypeScript
import { xor } from 'es-toolkit/array'

const result = xor(['a', 'b'], ['b', 'c'])
console.log(result)
// ['a', 'c']

xorBy

mapping関数を使用して、2つの配列の対称差分を計算して返します。

TypeScript
import { xorBy } from 'es-toolkit/array'

const result = xorBy([{ id: 1 }, { id: 2 }], [{ id: 2 }, { id: 3 }], x => x.id)
console.log(result)
// [{ id: 1 }, { id: 3 }]

xorWith

カスタム等式関数を使用して、2つの配列の対称差分を計算して返します。

TypeScript
import { xorWith } from 'es-toolkit/array'

const result = xorWith([{ id: 1 }, { id: 2 }], [{ id: 2 }, { id: 3 }], (a, b) => a.id === b.id)

console.log(result)
// [{ id: 1 }, { id: 3 }]

zip

複数の配列を1つのタプル配列にまとめる。

TypeScript
import { zip } from 'es-toolkit/array'

const arr1 = [1, 2, 3]
const arr2 = ['a', 'b', 'c']
const arr3 = [true, false]
const result = zip(arr1, arr2, arr3)
console.log(result)
// [[1, 'a', true], [2, 'b', false], [3, 'c', undefined]]

zipObject

プロパティ名と対応する値の2つの配列を1つのオブジェクトにまとめる。

TypeScript
import { zipObject } from 'es-toolkit/array'

const keys = ['a', 'b', 'c']
const values = [1, 2, 3]
const result = zipObject(keys, values)
console.log(result)
// { a: 1, b: 2, c: 3 }

zipWith

カスタム関数を使用して、複数の配列を1つの配列に結合します。

TypeScript
import { zipWith } from 'es-toolkit/array'

const arr1 = [1, 2, 3]
const arr2 = [4, 5, 6]
const result = zipWith(arr1, arr2, (a, b) => a + b)
console.log(result)
// [5, 7, 9]

まとめ

以上のようにArrayだけでも便利なメソッドがたくさんあります。

名前はlodashと同じものが多いので、lodashを使用したことがある方だと使いやすいと思います。

Function Utilitiesなどのその他のメソッドに関しては公式サイトのリファレンスを参照してください。

https://es-toolkit.slash.page/reference/function/debounce.html