Ramda,测试具有多个谓词的两个对象是否相等
Ramda, test two objects with multiple predicates for props equality
我有两个具有相同道具的对象。我创建了几个谓词来根据业务逻辑测试它们:
const eqId = eqProps('equipmentId');
const eqQuantity = eqProps('quantity');
const eqColor = eqProps('color');
每个谓词接受 (o1, o2) 作为参数。我正在寻找一种更好的方法来根据所有谓词传递输出单个值...换句话说:
predicates.every(predicate => predicate(o1, o2) === true)
但采用更 ramda 风格。 allPass
几乎可以工作,但它只接受一个对象。
我知道我可以用 every
做到这一点,但这个问题是为了帮助我了解更多如何组合函数。
我们需要嵌套 R.allPass
和 R.all
因为它是一个类似矩阵的问题
const a = { suit: '♠︎', rank: '4' };
const b = { suit: '♠︎', rank: '9' };
const isSpade = R.propEq('suit', '♠︎');
const isCard = R.has('suit');
const compareWith = R.pipe(
R.allPass,
R.all,
R.unapply,
);
const isASpadeCard = compareWith([isSpade, isCard])
console.log(
isASpadeCard(a, b),
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js" integrity="sha512-3sdB9mAxNh2MIo6YkY05uY1qjkywAlDfCf5u1cSotv6k9CZUSyHVf4BJSpTYgla+YHLaHG8LUpqV7MHctlYzlw==" crossorigin="anonymous"></script>
[...] allPass almost works but it accepts only a single object
也许我不是 100% 理解,但我认为那不是真的。文档说:
The function returned is a curried function whose arity matches that of the highest-arity predicate.
所以给定 eqProps('foo')
returns 一个二元函数那么 allPass
返回的函数也将是一个二元函数:
const check = allPass([eqProps('lunch'), eqProps('at')]);
check({lunch: '', at: '1pm'}, {lunch: '', at: '2pm'});
//=> false
check({lunch: '', at: '1pm'}, {lunch: '', at: '1pm'});
//=> true
如果您对对象的外观有一个“蓝图”,那么我发现 eqBy(whereEq)
更容易看清。
eqBy
最好用一个例子来说明。希望这不需要进一步解释:
const streqi = eqBy(toLower); // case insensitive equality
streqi("Foo", "fOO");
//=> true
所以回到eqBy(whereEq)
:
const check = eqBy(whereEq({lunch: '', at: '1pm'}))
check({lunch: '', at: '1pm', name: 'john'}, {lunch: '', at: '1pm', name: 'tom'});
//=> true
check({lunch: '', at: '1pm', name: 'john'}, {lunch: '', at: '2pm', name: 'tom'});
// ^ ^
//=> false
我有两个具有相同道具的对象。我创建了几个谓词来根据业务逻辑测试它们:
const eqId = eqProps('equipmentId');
const eqQuantity = eqProps('quantity');
const eqColor = eqProps('color');
每个谓词接受 (o1, o2) 作为参数。我正在寻找一种更好的方法来根据所有谓词传递输出单个值...换句话说:
predicates.every(predicate => predicate(o1, o2) === true)
但采用更 ramda 风格。 allPass
几乎可以工作,但它只接受一个对象。
我知道我可以用 every
做到这一点,但这个问题是为了帮助我了解更多如何组合函数。
我们需要嵌套 R.allPass
和 R.all
因为它是一个类似矩阵的问题
const a = { suit: '♠︎', rank: '4' };
const b = { suit: '♠︎', rank: '9' };
const isSpade = R.propEq('suit', '♠︎');
const isCard = R.has('suit');
const compareWith = R.pipe(
R.allPass,
R.all,
R.unapply,
);
const isASpadeCard = compareWith([isSpade, isCard])
console.log(
isASpadeCard(a, b),
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js" integrity="sha512-3sdB9mAxNh2MIo6YkY05uY1qjkywAlDfCf5u1cSotv6k9CZUSyHVf4BJSpTYgla+YHLaHG8LUpqV7MHctlYzlw==" crossorigin="anonymous"></script>
[...] allPass almost works but it accepts only a single object
也许我不是 100% 理解,但我认为那不是真的。文档说:
The function returned is a curried function whose arity matches that of the highest-arity predicate.
所以给定 eqProps('foo')
returns 一个二元函数那么 allPass
返回的函数也将是一个二元函数:
const check = allPass([eqProps('lunch'), eqProps('at')]);
check({lunch: '', at: '1pm'}, {lunch: '', at: '2pm'});
//=> false
check({lunch: '', at: '1pm'}, {lunch: '', at: '1pm'});
//=> true
如果您对对象的外观有一个“蓝图”,那么我发现 eqBy(whereEq)
更容易看清。
eqBy
最好用一个例子来说明。希望这不需要进一步解释:
const streqi = eqBy(toLower); // case insensitive equality
streqi("Foo", "fOO");
//=> true
所以回到eqBy(whereEq)
:
const check = eqBy(whereEq({lunch: '', at: '1pm'}))
check({lunch: '', at: '1pm', name: 'john'}, {lunch: '', at: '1pm', name: 'tom'});
//=> true
check({lunch: '', at: '1pm', name: 'john'}, {lunch: '', at: '2pm', name: 'tom'});
// ^ ^
//=> false