根據指定的 property 比較兩個 object 是否相等

Ramda 有兩個 Operator 長的非常像:propEq()eqProps(),初學者常常搞混,特別就這兩個 Operator 討論之。

Version


VS Code 1.31.1
Quokka 1.0.136
Ramda 0.26.1

propEq()


propEq()
String -> a -> Object -> Boolean
比對 object 的 property 與 value 是否相等

String:object 的 property

a:要比較的資料

Object:data 為 object

Boolean:若相等傳回 true,不相等傳回 false

由於 propEq() 的 currying 特性,只提供前兩個參數,剛好回傳 Object -> Boolean ,特別適合成為 predicate function

1
2
3
4
5
6
7
8
9
10
11
12
import { filter } from 'ramda';

const data = [
{ id: 1, title: 'Impatient JavaScript', year: 2018 },
{ id: 2, title: 'RxJS in Action', year: 2017 },
{ id: 3, title: 'Speaking JavaScript', year: 2014 },
];

const getTitle = val => filter(x => x.title === val);

const result = getTitle('RxJS in Action')(data);
console.dir(result);

第 9 行

1
const getTitle = val => filter(x => x.title === val);

想使用 filter() 找到指定 title 的 object,第一個參數為 predicate function,因此可使用 Arrow Function 表示。

eqprops000

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { filter, prop, equals, compose } from 'ramda';

const data = [
{ id: 1, title: 'Impatient JavaScript', year: 2018 },
{ id: 2, title: 'RxJS in Action', year: 2017 },
{ id: 3, title: 'Speaking JavaScript', year: 2014 }
];

const getTitle = val => filter(
compose(
equals(val),
prop('title')
)
);

const result = getTitle('RxJS in Action')(data);
console.dir(result);

由於 x.title 可使用 Ramda 的 prop(),而 === 可使用 Ramda 的 equals(),因此可用 compose() 動態組合出一個新 function 產生 predicate function。

eqprops001

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { propEq, filter } from 'ramda';

const data = [
{ id: 1, title: 'Impatient JavaScript', year: 2018 },
{ id: 2, title: 'RxJS in Action', year: 2017 },
{ id: 3, title: 'Speaking JavaScript', year: 2014 }
];

const getTitle = title => filter(
propEq('title', title)
);

const result = getTitle('RxJS in Action')(data);
console.dir(result);

由於 compose(equals(val), prop('title')) 這類 function 實在太常使用,因此 Ramda 提供了 propEq()

eqprops002

eqProps()


eqProps()
k → {k: v} → {k: v} → Boolean
根據指定的 property 比較兩個 object 是否相等

k:指定要比較 property 的 key

{k: v}:要比較的 source object

{k: v}:data 為要比較的 target object

Boolean:若相等傳回 true,不相等傳回 false

由於 eqProps() 的 currying 特性,只提供前兩個參數,剛好回傳 {k: v} -> Boolean ,特別適合成為 predicate function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { filter } from 'ramda';

const data = [
{ id: 1, title: 'Impatient JavaScript', year: 2018 },
{ id: 2, title: 'RxJS in Action', year: 2017 },
{ id: 3, title: 'Speaking JavaScript', year: 2014 }
];

const item = { title: 'RxJS in Action' };

const getTitle = item => filter(x => x.title === item.title);

const result = getTitle(item)(data);
console.dir(result);

11 行

1
const getTitle = item => filter(x => x.title === item.title);

想使用 filter() 找到指定 title 的 object,第一個參數為 predicate function,因此可使用 Arrow Function 表示。

由於 item 為 object,因此必須使用 item.title 才能抓到值。

eqprops003

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { filter, prop, compose, equals } from 'ramda';

const data = [
{ id: 1, title: 'Impatient JavaScript', year: 2018 },
{ id: 2, title: 'RxJS in Action', year: 2017 },
{ id: 3, title: 'Speaking JavaScript', year: 2014 }
];

const item = { title: 'RxJS in Action' };

const getTitle = item => filter(
compose(
equals(prop('title', item)),
prop('title')
)
);

const result = getTitle(item)(data);
console.dir(result);

由於 x.title 可使用 Ramda 的 prop(),而 === 可使用 Ramda 的 equals(),因此可用 compose() 動態組合出一個新 function 產生 predicate function。

由於 item 為 object,不能直接給 eqauls() 使用,必須先透過 prop() 取得 item.title

eqprops005

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { filter, eqProps } from 'ramda';

const data = [
{ id: 1, title: 'Impatient JavaScript', year: 2018 },
{ id: 2, title: 'RxJS in Action', year: 2017 },
{ id: 3, title: 'Speaking JavaScript', year: 2014 }
];

const item = { title: 'RxJS in Action' };

const getTitle = item => filter(
eqProps('title', item)
);

const result = getTitle(item)(data);
console.dir(result);

由於 compose(equals(prop('title', item)), prop('title')) 這類 function 實在太常使用,因此 Ramda 提供了 eqProps()

Q : 為什麼稱為 eqProps() 呢 ?

因為 item 為 object,使得 equals() 一定先得透過 prop() 取得值,所以稱為 eqProps()

eqprops004

Conclusion


  • propEq() 是 object 的 property 是否等於指定 value;而 eqProps() 是兩個 object 的指定 property 是否相等
  • 當參數為 value 時,會使用 propEq();當參數為 object 時,會使用 eqProps()

Reference


Ramda, propEq()
Ramda, eqProps()
Ramda, compose()
Ramda, prop()
Ramda, equals()