尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

es-toolkit/compat の `takeWhile` 完全ガイド:Lodash 互換の先頭連続要素取得を実装から理解する

es-toolkit/compat の `takeWhile` 完全ガイド:Lodash 互換の先頭連続要素取得を実装から理解する es-toolkit/compat のtakeWhile完全ガイドLodash 互換の先頭連続要素取得を実装から理解する【免费下载链接】es-toolkitA modern JavaScript utility library thats 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkittakeWhileは、配列の先頭から条件を満たし続ける限り要素を取得し、最初に条件を満たさない要素に到達した時点で停止するユーティリティ関数です。本記事では、es-toolkit/compatが提供する Lodash 互換のtakeWhileを対象に、4 種類の述語関数・部分オブジェクト・プロパティ値ペア・プロパティ名の使い分け、null/undefinedの扱い、そして ソースコード と テスト から読み取れる内部実装の仕組みまでを解説します。読了後には、Lodash からの移行時における挙動の差異を把握し、takeWhileを安全かつ高速に活用できるようになります。takeWhileとは何かtakeWhileは「配列の先頭から、条件predicateが真を返す間だけ要素を取り出して新しい配列を作る」関数です。filterと異なり、条件を満たさない要素が現れた時点で即座に走査を打ち切る点が最大の特徴です。そのため「先頭連続分だけを抜き出す」という用途に特化しています。const result takeWhile(array, predicate);たとえば[1, 2, 3, 4, 5]に対してx x 3という条件を与えると、1と2は条件を満たすため取得されますが、3で条件が偽になるためそこで停止し、結果は[1, 2]となります。使用前に知っておくべき注意点compat 版と現代版の使い分け本記事が解説するtakeWhileは、Lodash との互換性を目的としたes-toolkit/compatの実装です。es-toolkit の公式ドキュメントでは、以下の警告が明記されています。注意: es-toolkit のtakeWhileを使用してください。compat 版のtakeWhile関数は、nullやundefinedの処理などにより遅く動作します。代わりに、より高速で現代的な es-toolkit のtakeWhileを使用してください。つまり次の使い分けが推奨されています。状況推奨される関数インポート元Lodash からの移行で、既存の述語スタイル部分オブジェクト等をそのまま動かしたいes-toolkit/compatのtakeWhilees-toolkit/compat新規コードで純粋に関数述語のみを使い、最高のパフォーマンスを求めるes-toolkit 本体のtakeWhilees-toolkit/arraycompat 版は、後述するようにiterateeによる述語変換やisArrayLikeによる入力検証、toArrayによる配列化といった互換性処理を挟むため、その分オーバーヘッドが発生します。一方、es-toolkit 本体の実装 は単一のforループとbreakだけで構成されており、余計な処理が一切ありません。基本的な使い方関数条件による使用配列の先頭から条件を満たす間の要素を取得して新しい配列を作る、最もシンプルな使い方です。import { takeWhile } from es-toolkit/compat; // 関数条件を使用 const numbers [1, 2, 3, 4, 5]; takeWhile(numbers, x x 3); // Returns: [1, 2] // オブジェクト配列に対して条件関数を使用 const users [ { user: barney, active: false }, { user: fred, active: false }, { user: pebbles, active: true }, ]; takeWhile(users, o !o.active); // Returns: [{ user: barney, active: false }, { user: fred, active: false }]述語関数には「要素の値」「インデックス」「元の配列」の 3 つの引数が渡されますLodash と同じシグネチャです。// インデックスを利用 takeWhile([10, 20, 30, 40], (x, index) index 2); // Returns: [10, 20] // 元の配列を利用 takeWhile([1, 2, 3, 4], (x, index, arr) x arr.length); // Returns: [1, 2, 3]Lodash 互換のショートハンド述語compat 版の大きな価値は、Lodash と同じ4 種類の述語スタイルをすべてサポートしていることです。関数だけでなく、以下の記法がそのまま使えます。① 部分オブジェクトによる条件マッチング// 部分オブジェクトで条件マッチング takeWhile(users, { active: false }); // Returns: [{ user: barney, active: false }, { user: fred, active: false }]渡したオブジェクトの全プロパティと一致する要素だけが取得対象になります_.matches相当。② プロパティ-値配列による条件マッチング// プロパティ-値配列で条件マッチング takeWhile(users, [active, false]); // Returns: [{ user: barney, active: false }, { user: fred, active: false }]「プロパティ名」と「期待する値」の 2 要素配列で条件を表します_.matchesProperty相当。③ プロパティ名による真値チェック// プロパティ名で真と評価される値を確認 const items [{ active: true }, { active: true }, { active: false }]; takeWhile(items, active); // Returns: [{ active: true }, { active: true }]プロパティ名を文字列で渡すと、そのプロパティの値が真と評価されるtruthy間だけ要素が取得されます_.property相当。{ active: false }に到達した時点で停止するため、結果は先頭の 2 要素になります。nullやundefinedの扱いtakeWhileにnullやundefinedを渡すと、それらは空の配列として扱われ、常に[]が返ります。import { takeWhile } from es-toolkit/compat; takeWhile(null, x x 0); // [] takeWhile(undefined, x x 0); // []これは ソースコード の冒頭でisArrayLikeによるガードが行われているためです。null/undefinedは配列ライクではないため、即座に空配列が返されます。パラメータと戻り値項目型説明arrayArrayLikeT \| null \| undefined処理する配列。配列ライクなオブジェクト後述も受け付け、null/undefinedは空配列として扱われるpredicateListIterateeTオプション各要素に対して実行する条件。関数・部分オブジェクト・プロパティ-値配列・プロパティ名のいずれか。省略時は恒等関数identityがデフォルト戻り値T[]条件を満たす間、配列の先頭から取得した要素で構成される新しい配列述語を省略した場合の挙動は次の通りです。恒等関数が使われるため、trueやaのような truthy な値が続く限り要素が取得されます。takeWhile([a, b]); // [a, b] takeWhile([true, false]); // [true]内部実装の仕組み4 種類の述語はどう処理されるのかcompat 版takeWhileの中身は、驚くほど簡潔です。全体はわずか数行に凝縮されています。// src/compat/array/takeWhile.ts の実装要点抜粋 export function takeWhileT( array: ArrayLikeT | null | undefined, predicate?: ListIterateeT | PartialT | [keyof T, unknown] | PropertyKey ): T[] { if (!isArrayLike(array)) { return []; } const _array toArray(array); const index _array.findIndex(negate(iteratee(predicate ?? identity))); return index -1 ? _array : _array.slice(0, index); }処理の流れは次の 3 段階です。入力検証:isArrayLikeで配列ライクかどうかを判定し、違えば[]を返す。配列化:toArrayでArrayLikeTをT[]に変換する。境界探索とスライス:negate(iteratee(predicate))を述語にしたfindIndexで「最初に条件を満たさない要素のインデックス」を探し、slice(0, index)で先頭連続部分を取り出す。条件を一度も満たさない要素がなければindexは-1になるため、その場合は配列全体が返る。述語変換の中心iteratee4 種類の述語スタイルを 1 つに統合しているのが、iterateeです。この関数は、渡された値の型によって述語関数を生成し分けます。渡された値生成される述語Lodash 相当関数そのまま返す_.iteratee(func)長さ 2 の配列プロパティ-値ペアmatchesProperty(key, value)_.matchesPropertyオブジェクト部分オブジェクトmatches(object)_.matches文字列・数値・シンボルプロパティ名property(key)_.propertynull/ 未指定identity恒等関数_.identityつまりtakeWhile(users, [active, false])と書いた場合、内部的にはiteratee([active, false])がmatchesProperty(active, false)へ変換され、「activeプロパティがfalseと等しいか」を判定する関数として各要素に適用されます。この変換処理こそが compat 版の「Lodash 互換」の中核であり、同時にパフォーマンス差の要因でもあります。条件反転と探索negatefindIndex「条件を満たす間、先頭から取得する」という操作は、「条件を満たさなくなる最初の位置」を探す操作に言い換えられます。compat 版はこれをnegatesrc/compat/function/negate.tsで述語の結果を反転させ、Array.prototype.findIndexで最初の偽位置を特定する、というエレガントな方法で実現しています。述語を毎回評価してpushするのではなく、境界インデックスを一発で求めてsliceするため、コード量が極めて少なく抑えられています。テストが証明するエッジケースtakeWhile.spec.tsには、冒頭のドキュメント例に加えて、以下のエッジケースが網羅されています。述語へ渡される引数述語関数には(value, index, array)の 3 引数が渡されることがテストで検証されています。takeWhile(array, function () { args slice.call(arguments); }); // args [1, 0, array] 1 番目の要素、インデックス 0、元の配列ショートハンド述語の動作確認部分オブジェクト・プロパティ-値ペア・プロパティ名の各ショートハンドは、それぞれ以下の結果になることが確認されていますobjects [{ a: 2, b: 2 }, { a: 1, b: 1 }, { a: 0, b: 0 }]の場合。takeWhile(objects, { b: 2 }); // [{ a: 2, b: 2 }] takeWhile(objects, [b, 2]); // [{ a: 2, b: 2 }] takeWhile(objects, b); // [{ a: 2, b: 2 }, { a: 1, b: 1 }]プロパティ名ショートハンドbでは「bが truthy」である限り取得が続くため、b: 0falsyを含む 3 番目の要素の手前で停止します。配列ライクオブジェクトと文字列ArrayLikeTを受け付ける設計のため、インデックスとlengthを持つオブジェクトや、argumentsオブジェクトテストではtoArgsで生成もそのまま処理できます。さらに文字列は文字の配列として扱われます。takeWhile({ 0: 3, 1: 2, 2: 1, length: 3 }, value value 1); // [3, 2] takeWhile(hello, char char ! o); // [h, e, l, l] takeWhile(hello); // [h, e, l, l, o]これはtoArrayがArrayLike・Map・SetをArray.fromで配列化する実装に由来します。空配列・全件取得空配列を渡すと[]が返る。全要素が条件を満たす場合takeWhile([a, b])などは配列全体が返る。ソースコード上はfindIndexが-1を返し、index -1 ? _array : _array.slice(0, index)の分岐で_array全体がそのまま返される仕組みです。まとめtakeWhileの選択基準es-toolkit/compatのtakeWhileは、Lodash の_.takeWhileと完全な互換性を持つ関数です。関数・部分オブジェクト・プロパティ-値ペア・プロパティ名の 4 スタイルの述語をiterateeで統一的に処理します。null/undefinedは空配列、述語省略時は恒等関数、という Lodash と同じ仕様です。配列ライクオブジェクトや文字列にも対応し、内部ではnegatefindIndexsliceというコンパクトな実装で「先頭連続要素の取得」を実現しています。一方、Lodash 互換のオーバーヘッドを避けたい新規コードでは、es-toolkit 本体のtakeWhilees-toolkit/arrayからインポートが推奨されます。そちらは 単純なforループとbreakによる実装 で、述語は関数のみ・入力はreadonly T[]に限定される代わりに、余計な変換処理なしで高速に動作します。Lodash からの移行時は compat 版で挙動を維持し、新規実装では本体版を選ぶ——これが es-toolkit におけるtakeWhileの最適な使い分けです。【免费下载链接】es-toolkitA modern JavaScript utility library thats 2-3 times faster and up to 97% smaller, a major upgrade to lodash.项目地址: https://gitcode.com/GitHub_Trending/es/es-toolkit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表