はじめに

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つの引数(ab)を受け取り、以下のルールに従って数値を返します。

戻り値 意味
負の値 ab より前に配置
0 ab の順序を維持
正の値 ab より後ろに配置
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() は元の配列を変更するため、必要に応じてコピーを作成

これらのメソッドを適切に使い分けることで、配列操作のコードがより簡潔で読みやすくなります。実際のプロジェクトでは、複数のメソッドを組み合わせて使用することが多いため、それぞれの特徴をしっかり理解しておきましょう。

参考リンク