【GAS】someメソッド、everyメソッドの注意点(自分用メモ)
はじめに
前回までに、今度「お母さん」になられるコーチにプレゼントするLINE Bot、ペアプロでの設計全般についての学び1、設計全般についての学び2をメモしました。
今回もペアプロでの学びとして、配列に対するsomeメソッド、everyメソッドの注意点をメモしていきます。
配列.someメソッド、配列.everyメソッドの注意点
LINE BOTのコードでは、ユーザーの入力した筋トレメニューと、あらかじめ一次元配列に格納しておいたキーワードのどれかが一致するかを判定するために、someメソッドを使用していました。(後で、別の書き方に変えてしまったのですが)
someメソッド、何行かのfor of文やif文が1行にさらっと書けて、全体像も分かりやすくて超便利!と思っていたのですが、ペアプロではK先生が、someメソッドやその兄弟であるeveryメソッドについて、陥りやすい罠を教えてくださいました。
注意点
ではその罠とは?someメソッドやeveryメソッドは、配列の全ての要素を最後まで総当たりするわけではないということです。つまり
someならコールバック関数をtrueにする要素を1つ見つけた時点で処理を抜けてtrueを返す
everyならコールバック関数をfalseにする要素を1つ見つけた時点で処理を抜けてfalseを返す
(参考文献『JavaScript』(D.Flanagan, 第7版, P183))
someメソッドの例
たとえば、以下のmyFriends1のように、['Liz', 'Juliette', 'Caroline']という配列があって、「3文字の名前が1つでもあればtrueを返す」というsomeメソッドをきかせたとすると、Lizまで要素を調べた時点でこれがtrueなので、全体としてtrueが返り、JulietteとCarolineについては評価を行っていない、ということかと思っています。(どれか1個の要素について真なら全体として真を返す、という目的通り)
function testSome() {
const myFriends1 = ['Liz', 'Juliette', 'Caroline'];
const myFriends2 = ['Elizabeth', 'Juliette', 'Caroline'];
console.log(myFriends1.some(friend => friend.length === 3));//True ※3文字の要素(Liz)が存在するので
console.log(myFriends2.some(friend => friend.length === 3));//False ※3文字の要素が存在しないので
}
今の自分の知識の中で、someメソッドの代わりの関数funcSomeを書いてみると、以下のような感じになるでしょうか?
function testSome2() {
const myFriends1 = ['Liz', 'Juliette', 'Caroline'];
const myFriends2 = ['Elizabeth', 'Juliette', 'Caroline'];
const funcSome = array => {
for (const element of array) {
if (element.length === 3) { return true }
}
return false;
}
console.log(funcSome(myFriends1));//true ※3文字の要素(Liz)が存在するので
console.log(funcSome(myFriends2));//false ※3文字の要素が存在しないので
}
everyメソッドの例
everyについても同様に、以下のmyFriends2のように、 ['Meg', 'Elizabeth', 'Amy']という配列があって、「すべて3文字の名前であればtrueを返す」というeveryメソッドをきかせたとすると、Elizabethまで要素を調べた時点で、これがfalseなので全体としてfalseが返り、Amyについては評価を行っていない、ということかと思っています。(すべての要素について真なら全体として真を返す、すなわち、どれか1個の要素について偽なら全体として偽を返す、という目的通り)
function testEvery() {
const myFriends1 = ['Meg', 'Liz', 'Amy'];
const myFriends2 = ['Meg', 'Elizabeth', 'Amy'];
console.log(myFriends1.every(friend => friend.length === 3));//True ※全て3文字の要素なので
console.log(myFriends2.every(friend => friend.length === 3));//False ※3文字でない要素(Elizabeth)が存在するので
}
こちらも、今の自分の知識の中で、everyメソッドの代わりの関数funcEveryを書いてみると、以下のような感じでしょうか?
function testEvery2() {
const myFriends1 = ['Meg', 'Liz', 'Amy'];
const myFriends2 = ['Meg', 'Elizabeth', 'Amy'];
const funcEvery = array => {
for (const element of array) {
if (element.length !== 3) { return false }
}
return true;
}
console.log(funcEvery(myFriends1));//true ※全て3文字の要素なので
console.log(funcEvery(myFriends2));//false ※3文字でない要素(Elizabeth)が存在するので
}
everyはメソッド名的にも、全部の要素を網羅的に調べたような印象を持ちがちなので、その勘違いが元で何かやらかさないように気を付けたいと思います!