JavaScriptでのtakeWhileの実装-より良いアイデアを探しています

nmdr

Haskellには次のtakeWhile機能があります。

Prelude> takeWhile odd [1,3,5,7,8,9]
[1,3,5,7]

述語関数を適用すると結果がTrue。になる限り、リストから要素を「取得」します。になるFalseと止まります。

どうすればそれを実装できますか?

これが私が思いついたHaskellの再帰的アプローチです:

takewhile::(a->Bool)->[a]->[a]
takewhile _ [] = []
takewhile f (x:xs) | f x == True = x : takewhile f xs
                   | otherwise = []

述語f xTrueである限り、それ自体を呼び出し続けます。そうでない場合、それ自体を呼び出さずに空のリストを返します。

JavaScriptの次の実装を思い付くことができます。これは少し冗長であり、中間結果を渡すために別の関数の定義を呼び出します。

function takeWhile(f, xs) {
 return take(f, xs, [])
}

function take(f, xs, arr) {
 if(!xs || xs.length === 0) {
 return arr
 }
 x = xs.shift()
 if(f(x)) {
   arr.push(x)
   return take(f, xs, arr)
 } else {
   return arr
 }
}

takeWhile((x)=>{
 return x % 2 !== 0
},[1,3,5,7,9,11])

JavaScriptでそれを実装するためのより良いアイデアはありますか?

georg

takeWhileHSのように、つまり怠惰に実行したい場合は、JSにジェネレーターが必要です。

function* takeWhile(fn, xs) {
    for (let x of xs)
        if (fn(x))
            yield x;
        else
            break;
}

function* naturalNumbers() {
    let n = 0;
    while (true)
        yield n++;
}

result = takeWhile(x => x < 10, naturalNumbers())
console.log([...result])

HSコードのストレートポートも可能ですが、それはマテリアライズされた配列でのみ機能します(つまり、熱心に):

// would be nice, but JS sucks ;(
// let takeWhile = (f, [x, ...xs]) => f(x) ? [x, ...takeWhile(f, xs)] : [];

let takeWhile = (f, xs) => xs.length ? takeWhileNotEmpty(f, xs) : [];
let takeWhileNotEmpty = (f, [x, ...xs]) =>  f(x) ? [x, ...takeWhile(f, xs)] : [];


let odd = x => x % 2
a = [1,3,5,7,8,9]
r = takeWhile(odd, a)
console.log(r)

実際、@ naomikがここ示しているように、空のリストを処理するためのより良い方法があります。

let nil = {};
let takeWhile = (f, [x = nil, ...xs]) => (x === nil || !f(x)) 
    ? [] : [x, ...takeWhile(f, xs)];

console.log(takeWhile(x => x % 2, [1, 3, 5, 7, 8, 9]));

最後に、最初の試みには意味があります。これは、上記とは異なり、末尾再帰であるため、良いことです。より簡潔に書くことができます

let takeWhile = (f, xs) => take1(f, xs, []);
let take1 = (f, xs, acc) => xs.length ? take2(f, xs, acc) : acc;
let take2 = (f, [x, ...xs], acc) => f(x) ? take1(f, xs, acc.concat(x)) : acc;

両方のアプローチの組み合わせ(つまり、再帰ジェネレーター)は演習として残されました...

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

遺伝的アルゴリズムのより良い評価方法を探しています

分類Dev

VS10.NET形式でより動的なデザイナーTypeConverterシリアル化を探しています

分類Dev

IDからインデックスへの接続の変換を改善するためのより良いアルゴリズムまたはデータ構造を探しています

分類Dev

クエリでランクを決定するためのmysqlクエリでより良いアプローチを探しています

分類Dev

GRUB2メニューでアクセスを制限するためのより良い解決策を探しています

分類Dev

ジグザグ配列のより良い方法を探しています

分類Dev

react.jsでダイアログを実装するためのより良い方法はありますか?

分類Dev

Chef-IPアドレスの最後のオクテットを見つけるためのより良い方法を探しています。

分類Dev

マッチ3ジェム衝突検出のためのより良いアルゴリズムを探しています

分類Dev

STM32の動的割り当てなしのCでのデータ圧縮実装を探しています

分類Dev

このようなアイコンセットを探しています

分類Dev

List <Foo>からMap <String、List <Foo >>へ:より良い実装を探しています

分類Dev

Cで文字の配列をシフトするためのより良い方法を探しています

分類Dev

VimでFキーをマッピングするためのより良い方法を探しています

分類Dev

文字列配列を出力するためのより良い方法を探しています

分類Dev

このコードブロックのためのより良いPythonの慣習を探しています

分類Dev

シングルアクティビティアプリのアプローチでAndroidにSearchViewを実装するためのアイデアを探しています

分類Dev

文字配列または文字列の入力-より良い方法を探しています

分類Dev

.NETSmtpClientのトラブルシューティングのアイデアを探しています

分類Dev

Javaでデータベースを設計しようとしています。これまでのところ、必要なときに読み取って更新するシリアル化可能なオブジェクトがあります。良いアイデアか悪いアイデアか?

分類Dev

Linuxでtrをパイプするコマンドを書くためのより良い方法を探しています

分類Dev

マングースで更新するための最良のアプローチを探しています

分類Dev

ゼロではなく、アクティブレコード数がゼロより大きいことを確認するためのより良い方法を探しています

分類Dev

Azure SQLデータベースにアクセスするためのより良い方法をお探しですか?

分類Dev

メモリ内のイメージをファイルに保存するためのより良い方法を探しています

分類Dev

PHPで書かれていない「nextgen」CMSを探している...またはWordpressのより良い代替案

分類Dev

PHPで書かれていない「nextgen」CMSを探している...またはWordpressのより良い代替案

分類Dev

スパースファイルのディレクトリをバックアップおよび復元するための最良の方法を探しています

分類Dev

ssdとhddを使用して新しいPCでデュアルブートを設定するためのアドバイスを探しています

Related 関連記事

  1. 1

    遺伝的アルゴリズムのより良い評価方法を探しています

  2. 2

    VS10.NET形式でより動的なデザイナーTypeConverterシリアル化を探しています

  3. 3

    IDからインデックスへの接続の変換を改善するためのより良いアルゴリズムまたはデータ構造を探しています

  4. 4

    クエリでランクを決定するためのmysqlクエリでより良いアプローチを探しています

  5. 5

    GRUB2メニューでアクセスを制限するためのより良い解決策を探しています

  6. 6

    ジグザグ配列のより良い方法を探しています

  7. 7

    react.jsでダイアログを実装するためのより良い方法はありますか?

  8. 8

    Chef-IPアドレスの最後のオクテットを見つけるためのより良い方法を探しています。

  9. 9

    マッチ3ジェム衝突検出のためのより良いアルゴリズムを探しています

  10. 10

    STM32の動的割り当てなしのCでのデータ圧縮実装を探しています

  11. 11

    このようなアイコンセットを探しています

  12. 12

    List <Foo>からMap <String、List <Foo >>へ:より良い実装を探しています

  13. 13

    Cで文字の配列をシフトするためのより良い方法を探しています

  14. 14

    VimでFキーをマッピングするためのより良い方法を探しています

  15. 15

    文字列配列を出力するためのより良い方法を探しています

  16. 16

    このコードブロックのためのより良いPythonの慣習を探しています

  17. 17

    シングルアクティビティアプリのアプローチでAndroidにSearchViewを実装するためのアイデアを探しています

  18. 18

    文字配列または文字列の入力-より良い方法を探しています

  19. 19

    .NETSmtpClientのトラブルシューティングのアイデアを探しています

  20. 20

    Javaでデータベースを設計しようとしています。これまでのところ、必要なときに読み取って更新するシリアル化可能なオブジェクトがあります。良いアイデアか悪いアイデアか?

  21. 21

    Linuxでtrをパイプするコマンドを書くためのより良い方法を探しています

  22. 22

    マングースで更新するための最良のアプローチを探しています

  23. 23

    ゼロではなく、アクティブレコード数がゼロより大きいことを確認するためのより良い方法を探しています

  24. 24

    Azure SQLデータベースにアクセスするためのより良い方法をお探しですか?

  25. 25

    メモリ内のイメージをファイルに保存するためのより良い方法を探しています

  26. 26

    PHPで書かれていない「nextgen」CMSを探している...またはWordpressのより良い代替案

  27. 27

    PHPで書かれていない「nextgen」CMSを探している...またはWordpressのより良い代替案

  28. 28

    スパースファイルのディレクトリをバックアップおよび復元するための最良の方法を探しています

  29. 29

    ssdとhddを使用して新しいPCでデュアルブートを設定するためのアドバイスを探しています

ホットタグ

アーカイブ