亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

條件過濾,斷路取n

條件過濾,斷路取n

蠱毒傳說 2021-12-02 14:38:34
按條件過濾并在具有斷路的陣列中取前 n 個結果的最佳方法是什么?在預定義的項目列表上考慮搜索過濾器:[1, 2, 3, 4, 5, 6].filter(x => {  console.log(x);  return x < 4;}).take(2) === [1, 2];// 1// 2// true該take函數不存在,因為過濾器函數只返回一個數組,我想要流的斷路功能。是否有使用功能方法的組合會產生這種情況?IE// would not process 3, 4, 5, or 6 as the circuit would break at 2.take([1, 2, 3, 4, 5, 6], x => x < 4, 2) === [1, 2]如果沒有更多元素,該功能也應該停止。IEtake([1, 2, 3], x => x < 4, 4) === [1, 2, 3]
查看完整描述

3 回答

?
精慕HU

TA貢獻1845條經驗 獲得超8個贊

For 循環很聰明,因為它們可以完成它們的工作,它們只是老了,所以從所有像我這樣的時髦函數式程序員那里得到年齡歧視的評論。


let take = (arr, predicate, limit) => { 

  const results = [];

  const arrLength = arr.length 

  for (let i = 0; i < arrLength && results.length < limit; i++) { 

    if (predicate(arr[i])) { 

      results.push(arr[i]); 

    } 

  } 

  return results; 

}

無論如何,我很想知道其他人對此問題的解決方案,但這對我來說似乎非常有效......也許是原型墊片解決方案?


查看完整回答
反對 回復 2021-12-02
?
互換的青春

TA貢獻1797條經驗 獲得超6個贊

您可以使用生成器或可觀察對象以相當優雅的方式完成此操作。


發電機

我實際上為此專門開發了一個小的 npm 包。


使用這個包和 Ramda,你可以得到你想要的結果,如下所示:


在 RunKit 中嘗試


const { genTake, genFilter, genFrom, genToArray } = require("func-generators");

const { compose } = require('ramda');


const probe = x => (console.log(x),x);


const firstTwoUnderFour = compose(

    genToArray,

    genTake(2),

    genFilter(x => probe(x) < 4),  //  genFilter(x => x < 4),

    genFrom,    

);


console.log(firstTwoUnderFour([5,6,7,1,6,8,2,9,10,5]));  // [1, 2]

我在過濾謂詞中添加了一個探針,以顯示它正在處理哪些元素。您可以從控制臺輸出中看到它在到達 時立即停止2。

基本上,它在這里做的是:

  1. 從原始數組 ( genFrom)生成生成器函數

  2. 將該生成器函數轉換為僅生成與謂詞 ( genFilter(x => x < 4))匹配的值的生成器函數

  3. 將該生成器函數轉換為僅從步驟 2 ( genTake(2)) 中的一個生成前兩個值的生成器函數

  4. 將第 3 步中的生成器函數收斂到一個值數組 ( genToArray)

take從你發布的答案中更概括的可以寫成這樣:

const take = (arr, predicate, limit) => compose(

    genToArray,

    genTake(limit),

    genFilter(predicate),

    genFrom,

)(arr);

這甚至適用于無限的值序列:


在 RunKit 中嘗試


const { genTake, genFilter, genInfinite, genToArray } = require("func-generators");

const { compose } = require('ramda');


const firstFiveMultiplesOf125 = compose(

    genToArray,

    genTake(5),

    genFilter(x => x % 125 === 0),

);


console.log(firstFiveMultiplesOf125(genInfinite()));

最后要注意的一件事:我在這里使用 Ramda 的 compose 來提高可讀性,但您也可以嵌套這些函數調用,或者一個一個地調用它們:


const result = genToArray(gnTake(5, filter(x => x < 4, genFrom([1,2,3,4,5,6]))));


// or...


const gen = genFrom([1, 2, 3, 4, 5, 6]);

const first2 = genTake(2, genFilter(x => x < 4, gen));

const result = genToArray(first2);

可觀察對象

一種稍微重量級的方法是使用 Observables,例如RxJS庫:


在 RunKit 中嘗試


const { from } = require("rxjs")

const { take, filter, toArray } = require('rxjs/operators');


const probe = x => (console.log(x),x);


from([5,6,7,1,6,8,2,9,10,5]).pipe(

    filter(x => probe(x) < 4),

    take(2),

    toArray(),

).subscribe(xs => console.log(xs));    // [1, 2]

您也可以在此處看到它在到達 時立即停止檢查數組中的元素2。


查看完整回答
反對 回復 2021-12-02
?
繁星點點滴滴

TA貢獻1803條經驗 獲得超3個贊

for ... of如果結果數組的長度為 2,您可以使用惰性求值循環并退出。


var array = [1, 2, 3, 4, 5, 6],

    result = [];


for (let item of array) {

    if (item < 4) if (result.push(item) === 2) break;

}


console.log(result);


查看完整回答
反對 回復 2021-12-02
  • 3 回答
  • 0 關注
  • 187 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號