getArrayElementSatisfiesThePredicateIfSuchElementIsExactlyOne
- 一般技術名
- targetArray
- 日本語名
- 対象の配列
- 型
- ReadonlyArray<ArrayElement>
- 一般技術名
- predicate
- 日本語名
- プレディケート
- 型
- Predicate
- 一般技術名
- targetArray
- 日本語名
- 対象の配列
- 型
- ReadonlyArray<ArrayElement>
- 一般技術名
- predicate
- 日本語名
- プレディケート
- 型
- (arrayElement: string) => boolean
- 一般技術名
- options
- 日本語名
- オプション
- 型
- Options
- mustThrowErrorIfElementNotFoundOrMatchesAreMultiple
- 日本語名
- 対象の要素が見つからない、又は検索結果が2つ以上の場合に、エラーを投げる必要があるかどうか
- 型
- boolean (trueのみ)
- 必須
- はい
プレディケート(真偽値を返す関数)を満たす配列の 要素が只1つ
の場合、此の要素 を返す。 此の様な要素が無いか、2つ以上の場合、
- 3つ目の引数の値として
{ mustThrowErrorIfElementNotFoundOrMatchesAreMultiple: true }
が渡された場合、エラーが投げられる。 然し、関数の実行がエラー無しで終了した場合、TypeScriptは、返ってきた値がnull
ではなく、ジェネリック引数で指定された (此の場合は常に暗黙的)型であると 見做す。 - 3つ目の引数が渡されなかった場合、
null
が返される。 但し、返された値を、ジェネリック引数で指定された型の値 として利用するには、非null確認が必要に成る。
例
const sample: Array<string> = [ "Saint Paul", "Santa Barbara", "St. Louis", "Santa Monica" ];
「Santa」
から始まり、 3件が「Sa」
から始まっているが、「St.」 から始まっているのは1件のみである。const targetCityName: string | null = getArrayElementSatisfiesThePredicateIfSuchElementIsExactlyOne(
sample, (arrayElement: string): boolean => arrayElement.startsWith("St.")
);
プレディケートに依ると「St.」から始まるものが必要である。 上記の例の場合、此の条件を満たすものが丁度1個有る為、 3つ目の引数の要素が返される。
然し、実行する時には配列の中身は、事前に知られていない。 此の様に「St.」から始まる要素が期待されていても実際に1個存在している訳では なく、そもそも存在している訳もない。 其れで、此の引数の組み合わせだと、nullが返される可能性が有る。
console.log(targetCityName.length);
TypeScriptはエラーTS18047 (「'targetCityName' is possibly 'null'」)を投げる。 length
プロパティは文字列(と配列)には存在しているが、 targetCityName
はnull
に成っている可能性が有るのが 原因である。
length
を含め、文字列のプロパティや メソッドを呼び出す前には、targetCityName
は 非null
であることを保証 しなくてはならない。 if (targetCityName !== null) {}
の様に、条件文を使う事が一つの方法である。 此の場合、条件文の中にある値は 非null
であると、TypeScriptは見做す。 他の解決方法も有るが、TypeScriptが出来ると発言しているエンジニアが絶対に 使っては成らない表現は、targetCityName!.length
である。 コードの品質を大きく損なう為である。 普通、此の様な機能を使っているエンジニアは、any
型も幅広く使い、 其の他のTypeScriptを利用する事で得られる利点を無くしている、 有害な機能を使用している事が多い。
console.log(
getArrayElementSatisfiesThePredicateIfSuchElementIsExactlyOne(
sample, (arrayElement: string): boolean => arrayElement.startsWith("Santa")
)
);
プレディケートを満たす要素が2個なので、 nullが返される。 関数名を和訳すれば御分かりだと思うが、せっかく説明書を読んでくださっているので、翻訳では「丁度 1つの~要素」を含めると繰り返しておこう。
プレディケートを満たす要素が1個のみで、 其れ以外に成る事は無いと言い切れる場合、 { mustThrowErrorIfElementNotFoundOrMatchesAreMultiple: true }
を 3つ目の引数として渡す事が出来る。 結果として、TypeScriptは非null確認を求めないが、期待に反して プレディケートを満たす要素の数が丁度1個では なくなった場合、 UnexpectedEventError
が投げられる(思われるより此れの可能性が高い)。
const matching: string = getArrayElementSatisfiesThePredicateIfSuchElementIsExactlyOne(
sample,
(arrayElement: string): boolean => arrayElement.startsWith("Santa"),
{ mustThrowErrorIfElementNotFoundOrMatchesAreMultiple: true }
);
matching
の型としてstring | null
では なく、string
を指定出来る。 プレディケートを満たす要素が無かった場合か、此の様な要素が 2個以上の場合、null
が返されるのではなく、UnexpectedEventError
が投げられる。 勿論、此の例外をtry/catch
で処理出来るが、一般的には 上に考察された非null確認の使い方に比べて、特に利点は無い。ネイティブメソッドとの比較
下記ネイティブメソッドは getArrayElementSatisfiesThePredicateIfSuchElementIsExactlyOne
関数 より良くも無いが、悪くも無い。 何を使えば良いかは、下記の状況に於ける望ましい振る舞いに依って事と成る。
- プレディケートを満たしている配列要素が1つも 無い
- プレディケートを満たしている配列要素が 2つ以上有る
Array.prototype.find
getArrayElementSatisfiesThePredicateIfSuchElementIsExactlyOne
との 共通点は、両方がプレディケートを満たしている 要素を探している事。- プレディケートを満たしている要素が無い場合、
Array.prototype.find
はundefined
を返すが、getArrayElementSatisfiesThePredicateIfSuchElementIsExactlyOne
は 第3引数に依りnull
を返すか、エラーを投げる。 但しエラーを投げる事が選ばれた場合、TypeScriptは非null確認を求めない。Array.prototype.find
の場合は、非undefined確認が必要に成る為にgetArrayElementSatisfiesThePredicateIfSuchElementIsExactlyOne
を使いたく成る事が多い。 - プレディケートを満たしている要素が#2つ以上 の場合、
Array.prototype.find
は1つ目を返し、残っているものを 無視する。 此れに対して、getArrayElementSatisfiesThePredicateIfSuchElementIsExactlyOne
は プレディケートを満たしている要素を見つけてから、同じプレディケート を満たしている他の要素が無いかどうかを確認し、有った場合はどの要素も返さない。 配列要素を単に取得する事の他に、此の配列要素は他の要素と違う特性が有るか どうか(例えば唯一の識別子)、確認したい時に便利。
Array.prototype.filter
此のメソッドは、配列に在る特定の単一の 要素を取得する為ではなく、元の配列からの標本を取得する為にある。 此の様に、此の配列のメソッドが返していているのも 配列であり、即ちプレディケートを満たしている全ての 要素の配列である。
プレディケートを満たしている要素が無い場合、空の配列 が返される。 此の配列の何れの要素(1番目、つまり指数が 0個)にアクセスしても、undefined
が返される。 TypeScriptや、其の他の多数の静的型付けのプログラミング言語が此れについて 警告しない(例えば、Array<string>
又は string[]
は、文字通り「数が無限の文字列の 要素の配列」を意味しているが、事実上どの配列も 有限で、空に成っている事も有る)。
「IntelliJ IDEA」ファミリー統合開発環境に於ける高速入力

「IntelliJ IDEA」ファミリー の統合開発環境のLive templates 機能利用の恩恵に依り、関数呼び出し表現等の入力速度が向上する。 YDEEのライブテンプレートを取得するには、当ライブラリの正式プラグイン を導入する必要が有る。
Live Templateの利用手順
ライブテンプレートを使った事が無い場合でも、充実した内容の手順書が下記にある為、心配は無用である。 ライブテンプレートに慣れてしまえば、(キーボードのショートカット利用と同じ様な習慣)僅か数秒程度で下記の操作を行える。
- 配列を含む変数の名前か、配列表現をクリップボードにコピーして下さい。 結合開発環境が、
1つ目の
引数の位置に正しい値が入れられる様に、 getArrayElementSatisfiesThePredicateIfSuchElementIsExactlyOne関数 のLive templateを入力し始める前に、予め此れをクリップボードにコピーする習慣を作って下さい。 - getArrayElementSatisfiesThePredicateIfSuchElementIsExactlyOne関数の 名前を入力し始めて下さい。 オートコンプリートに依り、下記の2件が表示されます。
- アルファベット文字が丸に囲まれているアイコン:関数の名前のオートコンプリートで、結合開発環境の 規定の機能である。 Enterを押すと、関数の名前が入力され、必要に応じてインポートの 宣言も追加される。 悪くはないが、更に自動化が可能である。
- 版のアイコン:我々が必要なテンプレート。 Enterを一度押すと、テンプレートのコードが入力され、1つ目の引数 の位置はクリップボードの内容で埋められ、カーソルで選択できる。 此の説明に従えば、貼り付けされた値は不要なので、1つ目の引数の編集を終了するには もう一度Enterを押下する。
- プレディケート(アロー関数である)の引数の名前を入力して下さい。 此の引数は配列の要素だが、「element」より幅が狭い名前を付ける事を 御勧めします。 入力が終わったら、Tabを押して下さい。 今回、不要なオートコンプリートが邪魔に成る場合、先にEscを押してください。
- プレディケートの引数の名前を入力し
Enter
を押して下さい。 - 余計なコードを削除しておきましょう。