はじめに#
JavaScriptで配列を扱う際、「データを特定の順番で並び替えたい」「条件に合う要素を探したい」という場面は頻繁に発生します。商品を価格順にソートしたり、ユーザー一覧から特定の条件に合う人を見つけたりする処理は、Webアプリケーション開発において必須のスキルです。
本記事では、以下の内容を初心者向けにわかりやすく解説します。
sort() による配列の並び替えと比較関数の書き方
find() と findIndex() による条件に合う要素の検索
some() と every() による条件判定
- 各メソッドの使い分けと実践的な活用例
sort - 配列を並び替える#
sortの基本構文#
sort() メソッドは、配列の要素をその場(in-place)で並び替えます。元の配列自体が変更される点に注意してください。
1
2
|
array.sort();
array.sort(compareFn);
|
| 引数 |
説明 |
| compareFn |
要素の順序を決定する比較関数(省略可能) |
文字列のソート#
sort() を引数なしで呼び出すと、要素は文字列に変換され、UTF-16コードポイント順で昇順にソートされます。
1
2
3
4
5
6
7
|
const fruits = ["バナナ", "りんご", "みかん", "ぶどう"];
fruits.sort();
console.log(fruits); // ["ぶどう", "バナナ", "みかん", "りんご"]
const letters = ["c", "a", "b", "A", "B", "C"];
letters.sort();
console.log(letters); // ["A", "B", "C", "a", "b", "c"]
|
大文字と小文字では、大文字の方が先に並びます。これはUTF-16コードポイントの順序によるものです。
数値のソートには比較関数が必要#
数値の配列をそのままsort()すると、期待通りに並びません。これは要素が文字列として比較されるためです。
1
2
3
|
const numbers = [10, 2, 30, 4, 100];
numbers.sort();
console.log(numbers); // [10, 100, 2, 30, 4] ← 意図しない結果
|
「100」が「2」より前に来ているのは、文字列として比較すると「1」が「2」より小さいためです。
正しく数値をソートするには、比較関数を渡す必要があります。
1
2
3
4
5
6
7
8
9
|
const numbers = [10, 2, 30, 4, 100];
// 昇順ソート
numbers.sort((a, b) => a - b);
console.log(numbers); // [2, 4, 10, 30, 100]
// 降順ソート
numbers.sort((a, b) => b - a);
console.log(numbers); // [100, 30, 10, 4, 2]
|
比較関数の仕組み#
比較関数は2つの引数(aとb)を受け取り、以下のルールに従って数値を返します。
| 戻り値 |
意味 |
| 負の値 |
a を b より前に配置 |
| 0 |
a と b の順序を維持 |
| 正の値 |
a を b より後ろに配置 |
1
2
3
4
5
6
7
|
// 昇順: a - b
// a = 10, b = 2 の場合: 10 - 2 = 8 (正) → bが前に来る
// a = 2, b = 10 の場合: 2 - 10 = -8 (負) → aが前に来る
const numbers = [3, 1, 4, 1, 5, 9, 2, 6];
numbers.sort((a, b) => a - b);
console.log(numbers); // [1, 1, 2, 3, 4, 5, 6, 9]
|
オブジェクト配列のソート#
オブジェクトの配列を特定のプロパティでソートする場合も、比較関数を使用します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
const users = [
{ name: "田中", age: 25 },
{ name: "佐藤", age: 30 },
{ name: "鈴木", age: 20 }
];
// 年齢で昇順ソート
users.sort((a, b) => a.age - b.age);
console.log(users);
// [
// { name: "鈴木", age: 20 },
// { name: "田中", age: 25 },
// { name: "佐藤", age: 30 }
// ]
|
文字列プロパティでソートする場合は、localeCompare() を使用すると日本語も正しく並び替えられます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
const products = [
{ name: "りんご", price: 150 },
{ name: "みかん", price: 100 },
{ name: "ぶどう", price: 300 }
];
// 名前で昇順ソート(日本語対応)
products.sort((a, b) => a.name.localeCompare(b.name, "ja"));
console.log(products);
// [
// { name: "ぶどう", price: 300 },
// { name: "みかん", price: 100 },
// { name: "りんご", price: 150 }
// ]
|
sortは元の配列を変更する#
sort() は元の配列を直接変更(破壊的変更)します。元の配列を保持したい場合は、コピーを作成してからソートしてください。
1
2
3
4
5
6
7
8
9
10
11
|
const original = [3, 1, 4, 1, 5];
// 方法1: スプレッド構文でコピー
const sorted1 = [...original].sort((a, b) => a - b);
console.log(original); // [3, 1, 4, 1, 5](変更されない)
console.log(sorted1); // [1, 1, 3, 4, 5]
// 方法2: toSorted()を使用(ES2023以降)
const sorted2 = original.toSorted((a, b) => a - b);
console.log(original); // [3, 1, 4, 1, 5](変更されない)
console.log(sorted2); // [1, 1, 3, 4, 5]
|
toSorted() はES2023で追加されたメソッドで、元の配列を変更せずに新しいソート済み配列を返します。
find - 条件に合う最初の要素を取得する#
findの基本構文#
find() メソッドは、コールバック関数が true を返す最初の要素を返します。見つからない場合は undefined を返します。
1
2
|
const result = array.find(callbackFn);
const result = array.find(callbackFn, thisArg);
|
コールバック関数は以下の引数を受け取ります。
| 引数 |
説明 |
| element |
現在処理中の要素 |
| index |
現在の要素のインデックス(省略可能) |
| array |
findが呼び出された配列(省略可能) |
findの基本的な使い方#
条件に合う最初の要素を取得する場合に使用します。
1
2
3
4
5
6
7
8
9
|
const numbers = [5, 12, 8, 130, 44];
// 10より大きい最初の要素を検索
const found = numbers.find((num) => num > 10);
console.log(found); // 12
// 条件に合う要素がない場合
const notFound = numbers.find((num) => num > 200);
console.log(notFound); // undefined
|
オブジェクト配列での検索#
オブジェクトの配列から特定の条件に合う要素を見つける実践的な例です。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
const users = [
{ id: 1, name: "田中", role: "admin" },
{ id: 2, name: "佐藤", role: "user" },
{ id: 3, name: "鈴木", role: "user" }
];
// IDで検索
const user = users.find((user) => user.id === 2);
console.log(user); // { id: 2, name: "佐藤", role: "user" }
// roleで検索(最初に見つかった要素のみ)
const admin = users.find((user) => user.role === "admin");
console.log(admin); // { id: 1, name: "田中", role: "admin" }
|
findIndex - 条件に合う最初のインデックスを取得する#
findIndex() は find() と同じ動作ですが、要素の代わりにインデックスを返します。見つからない場合は -1 を返します。
1
2
3
4
5
6
7
|
const numbers = [5, 12, 8, 130, 44];
const index = numbers.findIndex((num) => num > 10);
console.log(index); // 1
const notFoundIndex = numbers.findIndex((num) => num > 200);
console.log(notFoundIndex); // -1
|
配列内の要素を更新や削除する際に、対象のインデックスを取得するために findIndex() がよく使われます。
1
2
3
4
5
6
7
8
9
10
11
|
const tasks = [
{ id: 1, title: "買い物", done: false },
{ id: 2, title: "掃除", done: true },
{ id: 3, title: "料理", done: false }
];
// id=2のタスクを完了状態に更新
const targetIndex = tasks.findIndex((task) => task.id === 2);
if (targetIndex !== -1) {
tasks[targetIndex].done = true;
}
|
findとfilterの違い#
find() と filter() は似ていますが、目的が異なります。
| メソッド |
戻り値 |
用途 |
| find() |
最初に見つかった要素1つ |
1つの要素を取得したい場合 |
| filter() |
条件に合う全要素の配列 |
複数の要素を取得したい場合 |
1
2
3
4
5
6
7
8
9
|
const numbers = [5, 12, 8, 130, 44];
// find: 最初の1つだけ
const firstLarge = numbers.find((num) => num > 10);
console.log(firstLarge); // 12
// filter: 条件に合うすべて
const allLarge = numbers.filter((num) => num > 10);
console.log(allLarge); // [12, 130, 44]
|
some - 条件を満たす要素が存在するか判定する#
someの基本構文#
some() メソッドは、配列内に条件を満たす要素が1つでもあれば true を返します。すべての要素が条件を満たさない場合は false を返します。
1
2
|
const result = array.some(callbackFn);
const result = array.some(callbackFn, thisArg);
|
someの基本的な使い方#
「少なくとも1つの要素が条件を満たすか」を確認する場合に使用します。
1
2
3
4
5
6
7
8
9
|
const numbers = [1, 2, 3, 4, 5];
// 偶数が存在するか
const hasEven = numbers.some((num) => num % 2 === 0);
console.log(hasEven); // true
// 10以上の数が存在するか
const hasLargeNumber = numbers.some((num) => num >= 10);
console.log(hasLargeNumber); // false
|
実践的な活用例#
ユーザーの権限チェックなど、実際のアプリケーションでよく使われるパターンです。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
const users = [
{ name: "田中", role: "user" },
{ name: "佐藤", role: "admin" },
{ name: "鈴木", role: "user" }
];
// 管理者が存在するかチェック
const hasAdmin = users.some((user) => user.role === "admin");
console.log(hasAdmin); // true
// 特定のユーザーが存在するかチェック
const hasYamada = users.some((user) => user.name === "山田");
console.log(hasYamada); // false
|
商品の在庫状況を確認する例です。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
const products = [
{ name: "りんご", stock: 0 },
{ name: "みかん", stock: 10 },
{ name: "ぶどう", stock: 5 }
];
// 在庫切れの商品があるか
const hasOutOfStock = products.some((product) => product.stock === 0);
console.log(hasOutOfStock); // true
// すべて在庫があるか(someの否定)
const allInStock = !products.some((product) => product.stock === 0);
console.log(allInStock); // false
|
someは早期終了する#
some() は条件を満たす要素が見つかった時点で処理を終了します。これにより、大きな配列でも効率的に検索できます。
1
2
3
4
5
6
7
8
9
10
|
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
numbers.some((num, index) => {
console.log(`インデックス ${index} を確認中`);
return num > 3;
});
// インデックス 0 を確認中
// インデックス 1 を確認中
// インデックス 2 を確認中
// インデックス 3 を確認中 ← ここで終了(4 > 3 がtrue)
|
every - すべての要素が条件を満たすか判定する#
everyの基本構文#
every() メソッドは、配列内のすべての要素が条件を満たす場合に true を返します。1つでも条件を満たさない要素があれば false を返します。
1
2
|
const result = array.every(callbackFn);
const result = array.every(callbackFn, thisArg);
|
everyの基本的な使い方#
「すべての要素が条件を満たすか」を確認する場合に使用します。
1
2
3
4
5
6
7
8
9
|
const ages = [18, 25, 30, 22, 19];
// 全員が18歳以上か
const allAdults = ages.every((age) => age >= 18);
console.log(allAdults); // true
// 全員が20歳以上か
const allOver20 = ages.every((age) => age >= 20);
console.log(allOver20); // false
|
実践的な活用例#
フォームのバリデーションでよく使われるパターンです。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
const formFields = [
{ name: "email", value: "test@example.com", valid: true },
{ name: "password", value: "secret123", valid: true },
{ name: "username", value: "", valid: false }
];
// すべてのフィールドが有効か
const isFormValid = formFields.every((field) => field.valid);
console.log(isFormValid); // false
// すべてのフィールドに値が入力されているか
const allFilled = formFields.every((field) => field.value.length > 0);
console.log(allFilled); // false
|
商品の在庫状況を確認する例です。
1
2
3
4
5
6
7
8
9
|
const cartItems = [
{ name: "りんご", quantity: 2, inStock: true },
{ name: "みかん", quantity: 3, inStock: true },
{ name: "ぶどう", quantity: 1, inStock: true }
];
// カート内のすべての商品が在庫ありか
const canCheckout = cartItems.every((item) => item.inStock);
console.log(canCheckout); // true
|
everyも早期終了する#
every() は条件を満たさない要素が見つかった時点で処理を終了します。
1
2
3
4
5
6
7
8
9
10
|
const numbers = [2, 4, 6, 7, 8, 10];
numbers.every((num, index) => {
console.log(`インデックス ${index} を確認中`);
return num % 2 === 0;
});
// インデックス 0 を確認中
// インデックス 1 を確認中
// インデックス 2 を確認中
// インデックス 3 を確認中 ← ここで終了(7は奇数なのでfalse)
|
空配列に対するeveryの挙動#
注意点として、空配列に対して every() を呼び出すと、常に true を返します。これは数学的な「空虚な真」の概念に基づいています。
1
2
|
const emptyArray = [];
console.log(emptyArray.every((x) => x > 0)); // true
|
空配列のケースを考慮する必要がある場合は、事前に配列の長さをチェックしてください。
1
2
3
4
5
|
const items = [];
// 空配列を考慮したチェック
const allValid = items.length > 0 && items.every((item) => item.valid);
console.log(allValid); // false
|
someとeveryの使い分け#
some() と every() は論理的に対になるメソッドです。
| メソッド |
意味 |
数学的記号 |
| some() |
少なくとも1つが条件を満たす |
存在記号(∃) |
| every() |
すべてが条件を満たす |
全称記号(∀) |
以下の関係が成り立ちます。
1
2
3
4
5
6
7
|
const numbers = [1, 2, 3, 4, 5];
// some と every の関係
// 「すべてが条件を満たす」の否定 = 「条件を満たさないものが1つでもある」
const allPositive = numbers.every((n) => n > 0);
const hasNonPositive = numbers.some((n) => n <= 0);
console.log(allPositive === !hasNonPositive); // true
|
判断フローチャートを以下に示します。
flowchart TD
A[条件をチェックしたい] --> B{何を知りたい?}
B -->|1つでも条件を満たすか| C[some を使用]
B -->|すべてが条件を満たすか| D[every を使用]
B -->|条件を満たす要素を取得したい| E{いくつ必要?}
E -->|最初の1つだけ| F[find を使用]
E -->|すべて| G[filter を使用]メソッドの使い分け一覧#
配列の検索・判定に関するメソッドの使い分けをまとめます。
| メソッド |
戻り値 |
用途 |
| find() |
最初の要素 or undefined |
条件に合う最初の要素を取得 |
| findIndex() |
インデックス or -1 |
条件に合う最初の要素の位置を取得 |
| some() |
true or false |
条件を満たす要素が1つでもあるか |
| every() |
true or false |
すべての要素が条件を満たすか |
| filter() |
新しい配列 |
条件を満たすすべての要素を取得 |
| includes() |
true or false |
特定の値が存在するか(完全一致) |
| indexOf() |
インデックス or -1 |
特定の値の位置を取得(完全一致) |
1
2
3
4
5
6
7
8
9
10
|
const numbers = [5, 12, 8, 130, 44];
// 各メソッドの比較
console.log(numbers.find((n) => n > 10)); // 12(最初の要素)
console.log(numbers.findIndex((n) => n > 10)); // 1(インデックス)
console.log(numbers.some((n) => n > 10)); // true(存在するか)
console.log(numbers.every((n) => n > 10)); // false(すべてか)
console.log(numbers.filter((n) => n > 10)); // [12, 130, 44](すべて)
console.log(numbers.includes(12)); // true(完全一致)
console.log(numbers.indexOf(12)); // 1(完全一致の位置)
|
実践例: 商品管理システム#
これまで学んだメソッドを組み合わせた実践的な例を紹介します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
const products = [
{ id: 1, name: "ノートPC", price: 89000, category: "電子機器", inStock: true },
{ id: 2, name: "マウス", price: 3500, category: "電子機器", inStock: true },
{ id: 3, name: "デスク", price: 25000, category: "家具", inStock: false },
{ id: 4, name: "チェア", price: 18000, category: "家具", inStock: true },
{ id: 5, name: "モニター", price: 35000, category: "電子機器", inStock: true }
];
// 1. 価格順にソート(安い順)
const sortedByPrice = [...products].sort((a, b) => a.price - b.price);
console.log("価格順:", sortedByPrice.map((p) => p.name));
// ["マウス", "チェア", "デスク", "モニター", "ノートPC"]
// 2. 特定のIDで商品を検索
const product = products.find((p) => p.id === 3);
console.log("ID=3の商品:", product?.name); // "デスク"
// 3. 在庫切れの商品があるかチェック
const hasOutOfStock = products.some((p) => !p.inStock);
console.log("在庫切れあり:", hasOutOfStock); // true
// 4. すべての商品が1万円以上かチェック
const allExpensive = products.every((p) => p.price >= 10000);
console.log("全商品1万円以上:", allExpensive); // false
// 5. カテゴリと在庫でフィルタリングしてからソート
const availableElectronics = products
.filter((p) => p.category === "電子機器" && p.inStock)
.sort((a, b) => a.price - b.price);
console.log("在庫あり電子機器(価格順):", availableElectronics);
// [{ マウス }, { モニター }, { ノートPC }]
|
まとめ#
本記事では、JavaScriptの配列のソートと検索に関する基本的なメソッドを解説しました。
sort() は配列を並び替えるメソッドで、数値のソートには比較関数が必要
find() と findIndex() は条件に合う最初の要素または位置を取得
some() は1つでも条件を満たす要素があるかを判定
every() はすべての要素が条件を満たすかを判定
sort() は元の配列を変更するため、必要に応じてコピーを作成
これらのメソッドを適切に使い分けることで、配列操作のコードがより簡潔で読みやすくなります。実際のプロジェクトでは、複数のメソッドを組み合わせて使用することが多いため、それぞれの特徴をしっかり理解しておきましょう。
参考リンク#