TL;DR
このページでは、JavaScript の find()
メソッドの実装方法について解説しますね。一言でいうと find()
メソッドとは、配列内の要素を検索し、最初に見つけた要素を返す関数です。
開発環境 | バージョン |
---|---|
Next.js | 13.4.4 |
TypeScript | 5.0.4 |
Emotion | 11.11.0 |
React | 18.2.0 |
find()
メソッドとは?
JavaScript の find()
メソッドは、配列内の各要素に対して指定した関数を実行し、その関数が真(true
)を返す最初の要素を返します。これは、例えばある条件を満たす要素を配列から探す際に非常に便利です。
以下に基本的なソースコードの例を示します。ここでは find()
メソッドを使って、配列から最初の奇数を見つける例を考えてみます。
const numbers = [2, 4, 5, 6, 8]
const firstOdd = numbers.find((num) => num % 2 !== 0)
console.log(firstOdd) // -> 5
このコードでは、配列 numbers
から find()
メソッドを使って最初の奇数を探しています。find()
メソッドには、検索条件を指定する関数(この場合は num => num % 2 !== 0
)を引数として渡します。この関数は、配列の各要素に対して実行され、真を返す最初の要素(この場合は 5
)が find()
メソッドの戻り値となります。
特定のユーザーを見つける例
それでは、Next.js と TypeScript を用いた具体的なコードを見てみましょう。ユーザーの情報が格納された配列から、特定のユーザーを見つける例を考えます。
以下の User
型と users
配列を考えます。
// models/user.ts
type User = {
id: number
name: string
}
const users: User[] = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Charlie' },
]
この users
配列から、特定の id
を持つユーザーを見つける関数 findUserById()
を実装します。
// utils/findUserById.ts
import { User, users } from '../models/user'
const findUserById = (id: number): User | undefined => {
return users.find((user) => user.id === id)
}
この findUserById()
関数では、引数としてユーザー ID を受け取り、find()
メソッドを使ってその ID を持つユーザーを users
配列から探します。find()
メソッドに渡す関数 user => user.id === id
では、各ユーザーの id
プロパティが引数の id
と等しいかどうかを確認します。該当するユーザーが見つかった場合はそのユーザーを、見つからなかった場合は undefined
を返します。
特定の条件を満たす要素を見つける
それでは、もう少し複雑な例を見てみましょう。複数のフィールドを持つ配列から、特定の条件を満たす要素を見つける例を考えます。
まず、以下のような商品の配列を考えます。
// models/item.ts
type Item = {
id: number
name: string
category: string
}
const items: Item[] = [
{ id: 1, name: 'T-shirt', category: 'clothing' },
{ id: 2, name: 'Jeans', category: 'clothing' },
{ id: 3, name: 'Sneakers', category: 'shoes' },
]
この items
配列から、特定のカテゴリーの最初の商品を見つける関数 findFirstItemByCategory()
を実装します。
// utils/findFirstItemByCategory.ts
import { Item, items } from '../models/item'
const findFirstItemByCategory = (category: string): Item | undefined => {
return items.find((item) => item.category === category)
}
この findFirstItemByCategory()
関数では、引数としてカテゴリーを受け取り、find()
メソッドを使ってそのカテゴリーの最初の商品を items
配列から探します。find()
メソッドに渡す関数 item => item.category === category
では、各商品の category
プロパティが引数の category
と等しいかどうかを確認します。該当する商品が見つかった場合はその商品を、見つからなかった場合は undefined
を返します。
アロー関数と分割代入の使用
アロー関数と分割代入を活用して、先ほどの findUserById
関数をより見やすく書くことができます。具体的には、find
メソッドの引数として渡す関数内で分割代入を使用します。
// utils/findUserById.ts
import { User, users } from '../models/user'
const findUserById = (id: number): User | undefined => {
return users.find(({ id: userId }) => userId === id)
}
この書き方では、配列の各要素(ここでは user
オブジェクト)を分割代入して id
プロパティを userId
という名前で直接取り出しています。これにより、コードがより簡潔になり、user.id
と書くよりも読みやすくなります。
要素が複数ある場合
find
メソッドは配列の要素が条件を満たすものが複数ある場合でも、最初に見つかった要素だけを返します。もし条件を満たす全ての要素を取得したい場合は、filter
メソッドを使用します。
以下の例では、特定のカテゴリーに属する全ての商品を見つける関数 findAllItemsByCategory
を実装しています。
// utils/findAllItemsByCategory.ts
import { Item, items } from '../models/item'
const findAllItemsByCategory = (category: string): Item[] => {
return items.filter((item) => item.category === category)
}
この関数では、引数としてカテゴリーを受け取り、filter
メソッドを使ってそのカテゴリーの全ての商品を items
配列から探します。filter
メソッドに渡す関数 item => item.category === category
では、各商品の category
プロパティが引数の category
と等しいかどうかを確認します。該当する商品が見つかった場合はその商品を配列として、見つからなかった場合は空の配列を返します。
他の引数について
find
メソッドに渡す関数は、引数として配列の各要素だけでなく、その要素のインデックスや元の配列も受け取ることができます。以下の例では、findWithIndex
関数を実装して、配列の要素とそのインデックスを同時に取得します。
// utils/findWithIndex.ts
import { User, users } from '../models/user'
const findWithIndex = (id: number): [User | undefined, number] => {
let foundUser: User | undefined
let foundIndex: number = -1
users.find((user, index) => {
if (user.id === id) {
foundUser = user
foundIndex = index
return true
}
return false
})
return [foundUser, foundIndex]
}
この関数では、find
メソッドのコールバック関数が要素 user
とそのインデックス index
の両方を引数として受け取ります。見つけた要素とそのインデックスを保持するための変数 foundUser
と foundIndex
を用意して、条件に一致した要素が見つかった時点でその値を更新しています。このようにして、見つけた要素とそのインデックスを一緒に返すことができます。