JavaScript の Array.some
と Array.includes
は、
どちらも配列に特定の要素が存在するか判定するのに使えます。
Array.some
とArray.includes
をどのように使い分ければいいのかを考えたいと思います。
古えの JavaScript では...
ES2015 でArray.some
が追加されるまで、配列にある要素が存在するか判定するには、
(本来の用途と違うため)直感的でないindexOf
や、for
文で冗長な記述をする必要がありました。
const chars = ["a", "b", "d", "g", "h", "i", "m", "n"];
const target = "d";
// for 文でループして探す
let exists = false;
for (const char of chars) {
if (char === target) {
exists = true;
break;
}
}
console.log(exists);
// インデックスが 0 より大きかったら存在する
exists = chars.indexOf(target) >= 0;
console.log(exists);
Array.some
と Array.includes
の実装後
ES2015 でArray.some
、ES2017でArray.includes
が追加されました。
どちらも配列に特定の要素が含まれるかを直感的・簡潔に書くことができます。
includes
は特定の要素が配列に含まれているかどうかをtrue
/ false
で返します。
const chars = ["a", "b", "d", "g", "h", "i", "m", "n"];
const target = "d";
const exists = chars.includes(target);
console.log(exists); // => true
some
は配列の少なくとも1つの要素が、渡されたテスト関数を通るかどうかをtrue
/ false
で返します。
const chars = ["a", "b", "d", "g", "h", "i", "m", "n"];
const target = "d";
const exists = chars.some(c => c === target);
console.log(exists);
オブジェクトの配列でArray.includes
を使ってみる
Array.includes
でBook
オブジェクトの配列から対象の本を探してみます。
const books = [
{ title: "幼年期の終り", author: "アーサー・C・クラーク" },
{ title: "1984年", author: "ジョージ・オーウェル" },
{ title: "われはロボット", author: "アイザック・アシモフ" }
];
const target = {
title: "1984年",
author: "ジョージ・オーウェル"
};
const includes = books.includes(target);
console.log(`includes: ${includes}`); // includes: false
同じオブジェクトがあるように見えますが、結果はfalse
が返ります。
オブジェクトの比較は参照が比較される
オブジェクトを比較するとき、その比較は同じ参照を指しているかどうかがテストされます。
includes
による比較も同様です。
つまり、以下のようなコードならArray.includes
はtrue
を返します。
const books = [
{ title: "幼年期の終り", author: "アーサー・C・クラーク" },
{ title: "1984年", author: "ジョージ・オーウェル" },
{ title: "われはロボット", author: "アイザック・アシモフ" }
];
const target = books[1];
const includes = books.includes(target);
console.log(`includes: ${includes}`); // includes: true
要素がオブジェクトの配列にはArray.some
Array.some
は引数にテスト関数を渡すことができます。
オブジェクトの値型のプロパティがすべて等しいか調べるテスト関数を渡すことで、
要素がオブジェクトの配列に特定の要素が含まれているかを簡単に調べることができます。
const books = [
{ title: "幼年期の終り", author: "アーサー・C・クラーク" },
{ title: "1984年", author: "ジョージ・オーウェル" },
{ title: "われはロボット", author: "アイザック・アシモフ" }
];
const target = {
title: "1984年",
author: "ジョージ・オーウェル"
};
const some = books.some(
b => b.title === target.title && b.author === target.author
);
console.log(`some: ${some}`); // some: true
Array.some
は要素1つ1つに対しテスト関数を反復実行し、
テスト関数をパスする要素が見つかった時点でtrue
を返し処理を終了します。
まとめ
要素が値型の配列にはArray.includes
要素が参照型の配列(または条件を詳しく指定したい時)にはArray.some
と使い分けるといいと思います。