2017-01-02 80 views
4

我想写一个函数,其规范在下面的代码片段中描述,这是我目前的实现。它确实有效。不过,我一直试图将它写成无缺陷的,完全是作为ramda函数的组合,并且找不到解决方案。这个问题与obj => map(key => recordSpec[key](obj[key])有关,我无法以一种可以完全无缺点的方式来减少这个问题。Ramda类型检查助手

我该怎么办?

/** * check that an object : * - does not have any extra properties than the expected ones (strictness) * - that its properties follow the defined specs * Note that if a property is optional, the spec must include that case * @param {Object.<String, Predicate>} recordSpec * @returns {Predicate} * @throws when recordSpec is not an object */ function isStrictRecordOf(recordSpec) { return allPass([ // 1. no extra properties, i.e. all properties in obj are in recordSpec // return true if recordSpec.keys - obj.keys is empty pipe(keys, flip(difference)(keys(recordSpec)), isEmpty), // 2. the properties in recordSpec all pass their corresponding predicate // For each key, execute the corresponding predicate in recordSpec on the // corresponding value in obj pipe(obj => map(key => recordSpec[key](obj[key]), keys(recordSpec)), all(identity)), ] ) }

例如,为了实现这一目标是使用R.where,这需要一个规范的对象喜欢你recordSpec,并与值从的对应键适用每个谓词 isStrictRecordOf({a : isNumber, b : isString})({a:1, b:'2'}) -> true isStrictRecordOf({a : isNumber, b : isString})({a:1, b:'2', c:3}) -> false isStrictRecordOf({a : isNumber, b : isString})({a:1, b:2}) -> false

回答

2

的一种方式第二个对象。然后

你的函数看起来像:

const isStrictRecordOf = recordSpec => allPass([ 
    pipe(keys, flip(difference)(keys(recordSpec)), isEmpty), 
    where(recordSpec) 
]) 
+0

哇,比我预期的要短。非常感谢。很难掌握众多的ramda函数。我仍然想知道,如果“没有想到”,那么人们会怎样去解决这个问题。但无论如何,如果测试通过,我愿意测试答案并接受它 – user3743222