比较ramda.js中的部分对象

时间:2016-05-04 06:25:20

标签: javascript ramda.js

Ramdajs中有一个等于完全棒的的函数,它将提供以下内容:

// (1) true
R.equals({ id: 3}, { id: 3})

// (2) true
R.equals({ id: 3, name: 'freddy'}, { id: 3, name: 'freddy'})

// (3) false
R.equals({ id: 3, name: 'freddy'}, { id: 3, name: 'freddy', additional: 'item'});

我将如何改进此功能,或以其他方式为true生成3结果

我想忽略rValue中不存在的lValue的所有属性,但要忠实地比较其余内容。我希望equals的递归性质保持不变 - 如果可能的话。

我做了一个简单的fiddle,显示了上面的结果。

4 个答案:

答案 0 :(得分:6)

equals有一个约束,以便与需要equals(a, b) === equals(b, a)对称的Fantasy Land规范很好地匹配,所以为了满足你的情况,我们需要把对象变成一些用于比较的等效形状。

我们可以通过创建第二个对象的新版本来实现这一目标,该第二个对象已删除了第一个对象中不存在的所有属性。

const intersectObj = (a, b) => pick(keys(a), b)

// or if you prefer the point-free edition
const intersectObj_ = useWith(pick, [keys, identity])

const a = { id: 3, name: 'freddy' },
      b = { id: 3, name: 'freddy', additional: 'item'}

intersectObj(a, b) // {"id": 3, "name": "freddy"}

使用它,我们现在可以根据第一个对象a中存在的属性比较两个对象。

const partialEq = (a, b) => equals(a, intersectObj(a, b))

// again, if you prefer it point-free
const partialEq_ = converge(equals, [identity, intersectObj])

partialEq({ id: 3, person: { name: 'freddy' } },
          { id: 3, person: { name: 'freddy' }, additional: 'item'})
//=> true

partialEq({ id: 3, person: { name: 'freddy' } },
          { id: 3, person: { age: 15 }, additional: 'item'})
//=> false

答案 1 :(得分:0)

我之前没有使用过Ramda.js,如果我的回答出现问题,请随意指出。

我学习了Ramda.js的源代码

src/equals.js中,定义了您使用的功能。

var _curry2 = require('./internal/_curry2');
var _equals = require('./internal/_equals');

module.exports = _curry2(function equals(a, b) {
  return _equals(a, b, [], []);
});

所以它只是将函数equals(内部称为_equals)放入"咖喱"。

因此,让我们查看内部_equals函数,确实检查了行84~86中的长度:

if (keysA.length !== keys(b).length) {
  return false;
}

只需对这些行进行评论即可true

<小时/> 您可以1)只在Ramda的分布式版本中评论这3行,或2)您可以添加自己的partialEquals函数然后重新构建并创建您的Ramda版本(更推荐,来自我的观点看法)。如果您需要任何帮助,请不要犹豫与我讨论。 :)

答案 2 :(得分:0)

这也可以通过whereEq

来完成
R.findIndex(R.whereEq({id:3}))([{id:9}{id:8}{id:3}{id:7}])

答案 3 :(得分:0)

使用whereEq

从文档中:“获取一个规范对象和一个测试对象;如果测试满足规范,则返回true,否则返回false。”

whereEq({ id: 3, name: 'freddy' }, { id: 3, name: 'freddy', additional: 'item' })

另一种方法是开发自己的版本。归结为:

if (is object):
  check all keys - recursive
otherwise:
  compare using `equals`

这是递归的无点版本,可处理深层对象,数组和非对象值。

const { equals, identity, ifElse, is, mapObjIndexed, useWith, where } = R

const partialEquals = ifElse(
  is(Object),
  useWith(where, [
    mapObjIndexed(x => partialEquals(x)),
    identity,
  ]),
  equals,
)

console.log(partialEquals({ id: 3 }, { id: 3 }))
console.log(partialEquals({ id: 3, name: 'freddy' }, { id: 3, name: 'freddy' }))
console.log(partialEquals({ id: 3, name: 'freddy' }, { id: 3, name: 'freddy', additional: 'item' }))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>