.find()、.some()、.includes()、.indexOf() 比較すれば違いが分かる
今日もArrayメソッドについて復習する。
.find()、.some()、.includes()、.indexOf() この4つは何となく似ていて、混乱しやすいので
まとめて比較して頭の整理をしたい。いずれもArrayの中で何か探すイメージなのだが・・・
Arrayの中にありますか?系メソッド
.find(): Arrayの中から「最初に条件に合ったもの」を「1つReturnする」※条件に合うものが2つ以上あっても、1つ目だけで探すのやめる。条件に合うものがなかったらundefinedが返ってくる。
.some(): ある条件に対して、Arrayの中に「最低でも1つはTrueになるもの」があれば「True」を返す。※条件をクリアするものが一つもなければFalseが返る。Trueとしか返ってこないので、中身は分からない。
.includes(): 「具体的な値など」がArrayの中に含まれていれば「True」を返す。※10以上の数字などの条件検索は使えない。
.indexOf(): 「具体的な値など」がArrayの中に含まれていれば最初に見つかったのがArrayの何番目にあるかIndexを返す。一つもなければ「−1」が返る。※同じ値が2つ以上含まれているArrayの場合は1つ目の場所しか返ってこない。
便利そうなのに、制約が多い?
TrueかFalseかだけ分かればいい、1つ目だけでいい、という場合はもちろん問題ないのだが、
何となく不十分だと感じる場面があったとしたら、.filter()メソッドで解決できるかもしれない。
.find(): Arrayの中から「最初に条件に合ったもの」を「1つReturnする」※条件に合うものが2つ以上あっても、1つ目だけで探すのやめる。条件に合うものがなかったらundefinedが返ってくる。
→ もし条件に合うもの全てReturnしたいのならfilter()
.some(): ある条件に対して、Arrayの中に「最低でも1つはTrueになるもの」があれば「True」を返す。※条件をクリアするものが一つもなければFalseが返る。Trueとしか返ってこないので、中身は分からない。
→ もし条件に合うものの中身をReturnしたいのならfilter()
→ 全てが条件をクリアするかどうかを知りたいならevery()。
.includes(): 「具体的な値など」がArrayの中に含まれていれば「True」を返す。※10以上の数字などの条件検索は使えない。文字列のときは大文字と小文字が区別される。
→ もし条件に合うものの中身をReturnしたいのならfilter()
.indexOf(): 「具体的な値など」がArrayの中に含まれていれば最初に見つかったのがArrayの何番目にあるかIndexを返す。一つもなければ「−1」が返る。※同じ値が2つ以上含まれているArrayの場合は1つ目の場所しか返ってこない。
→ もし条件に合うものの中身をReturnしたいのならfilter()
こんな風に書くと.filter()推しみたいに聞こえてしまうかもしれないので、
この4つがどういう時に使うのが便利なのかを見ていきたい。
.find()でArray内のobjectから検索
データに重複が無いのであれば、.find()を使うと必要な情報を取りやすい。
.filter()でももちろん同じことができるが、.find()は、条件に合うものが1つ見つかったところで探すのやめるので、無駄が少ない。.filter()は1つ見つかった後も全てを見にいく。
const platypuses = [
{ name: "Perry", age: 11, gender: "male" },
{ name: "Mary", age: 9, gender: "female" },
{ name: "B.B", age: 13, gender: "male" },
{ name: "Ollie", age: 6, gender: "male" },
{ name: "Yammy", age: 5, gender: "female" },
{ name: "Milo", age: 8, gender: "male" },
{ name: "Emma", age: 12, gender: "female" },
{ name: "Luna", age: 7, gender: "female" },
];
const Perry = platypuses.find((platypus) => platypus.name === "Perry");
console.log(Perry);
// Output: {name: 'Perry', age: 11, gender: 'male'}
.some()の使い道
個人的には使いづらいsome。例えば、find()と合わせて「X歳以下の子供が1人でもいる親を返したい」という場合や、「一つでもOOな状態」かどうかをチェックするときに使われている。具体的にはチェックが入っていないチェックボックスが一つでも残っていればTrueを返して、表示を変えるというような時に使える。
function CheckboxForm() {
const [checkboxes, setCheckboxes] = useState([
{ id: 1, label: "Checkbox 1", checked: false },
{ id: 2, label: "Checkbox 2", checked: false },
{ id: 3, label: "Checkbox 3", checked: false },
]);
const [message, setMessage] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
//チェックが入っていないチェックボックスが一つでも残っていればTrue
const isAnyUnchecked = checkboxes.some((checkbox) => !checkbox.checked);
if (isAnyUnchecked) {
setMessage("Please check all checkboxes.");
} else {
setMessage("Form submitted successfully!");
}
};
return <p>{message}</p>;
}
.includes()で指定した値の子を持つ親を返す
find()と合わせることで指定した値の子を持つ親を返すことができる。(※なお”Child 2″という同じ値が複数存在し、すべての親を返したいのであればfilter()を使う)
const familyTree = [
{ name: 'Parent 1', children: ['Child 1', 'Child 2'] },
{ name: 'Parent 2', children: ['Child 3', 'Child 4'] },
{ name: 'Parent 3', children: ['Child 5', 'Child 6'] }
];
const familyOfTheChild = familyTree.find(family => family.children.includes('Child 2'));
console.log(familyOfTheChild);
// Output: { name: 'Parent 1', children: ['Child 1', 'Child 2'] }
.indexOf()と.splice()でIDを削除
.indexOf()は.splice()と合わせて使うと便利。IDナンバーを指定して、データを削除できる。
const users = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' },
{ id: 3, name: 'Bob' }
];
const idToDelete = 2;
const index = users.findIndex(user => user.id === idToDelete);
// IDが存在しない場合には -1が返る
if (index !== -1) {
users.splice(index, 1);
}
console.log(users);
// Output: [{ id: 1, name: 'John' }, { id: 3, name: 'Bob' }]
これじゃないとできないというものはない
今回復習した .find()、.some()、.includes()、.indexOf()いずれもこれを使わないといけないというものは一つもない。基本的には他のメソッドでも同じ結果を達成できる。ただ、何となくfind()などの名前に引っ張られて、使いたくなる場面は多いのだが、書いてみたけど、思っていたのと違う結果が出てきたりして「ん?これじゃなかったかな」となる時があったので、まとめておいた。
というわけで本日は以上!
WordPressに苦戦したけど、
ようやく落ち着いた(妥協した)
