點燈坊

失くすものさえない今が強くなるチャンスよ

使用 takeWhile() 根據自訂條件取得 Array 前幾筆資料

Sam Xiao's Avatar 2019-07-16

take() 只能取得 Array 固定前幾筆資料,若想自行提供自訂條件 Predicate,就得使用 takeWhile()

Version

macOS Mojave 10.14.5
VS Code 1.36.1
Quokka 1.0.233
Ramda 0.26.1

Imperative

let data = [1, 3, 2, 4];

// takeWhile :: (a -> Boolean) -> [a] -> [a]
let takeWhile = pred => arr => {
  let result = [];

  for (let elm of arr) {
    if (pred(elm)) {
      result.push(elm);
    } else {
      break;
    }
  }

  return result;
};

takeWhile(x => x % 2)(data); // ?

takeWhile() 意義為當 predicate 為 true 時回傳 element,直到 false 時停止回傳。

建立 takeWhile(),imperative 會使用 for loop,並先建立好回傳的 result array,當符合 pred() 時,elem 會塞進回 array,最後會回傳 result 結束執行。

takewhile000

Ramda

import { takeWhile } from 'ramda';

let data = [1, 3, 2, 4];

takeWhile(x => x % 2)(data); // ?

Ramda 已經提供 takeWhile(),可直接使用。

takeWhile()
(a → Boolean) → [a] → [a]
根據自訂條件取得 array 前幾筆資料

(a -> Boolean):自訂條件 predicate

[a]:data 為 array

[a]:回傳 array 前幾筆資料

takewhile001

Point-free

import { takeWhile, compose, modulo, __, equals } from 'ramda';

let data = [1, 3, 2, 4];

let pred = compose(
  equals(1),
  modulo(__, 2)
);

takeWhile(pred)(data); // ?

也可將 x => x % 2 進一步 point-free。

  • 使用 modulo(__, 2) 取得餘數,相當於 % 2
  • 使用 equals(1) 判斷相等,相當於 === 1

最後使用 compose() 組合所有 function,非常清楚。

takewhile002

Object

import { takeWhile  } from 'ramda';

let data = [
  { title: 'FP in JavaScript', price: 101 },
  { title: 'RxJS in Action', price: 203 },
  { title: 'Speaking JavaScript', price: 300 }
];

console.dir(takeWhile(x => x.price % 2)(data)); 

takeWhile() 也能用在 object。

takewhile003

Point-free

import { takeWhile, compose, prop, modulo, __, equals  } from 'ramda';

let data = [
  { title: 'FP in JavaScript', price: 101 },
  { title: 'RxJS in Action', price: 203 },
  { title: 'Speaking JavaScript', price: 300 }
];

let pred = compose(
  equals(1),
  modulo(__, 2), 
  prop('price')
);

console.dir(takeWhile(pred)(data));

也可將 x => x.price % 2 進一步 point-free。

  • 使用 prop('price') 取得 property 值,相當於 x.price
  • 使用 modulo(__, 2) 取得餘數,相當於 % 2
  • 使用 equals(1) 判斷相等,相當於 === 1

最後使用 compose() 組合所有 function,非常清楚。

takewhile004

Conclusion

  • takeWhle()filter() 用法很類似,但 filter() 是取得符合條件所有資料,而 takeWhile() 是取得符合條件前 n 筆資料

Reference

Ramda, takeWhile()
Ramda, compose()
Ramda, equals()
Ramda, modulo()
Ramda, prop()