如何使用Ramda从对象中过滤出特定的键?

时间:2017-04-10 20:27:30

标签: javascript object functional-programming ramda.js

http://ramdajs.com/0.21.0/docs/#prop

Ramda Repl

var myObject = {a: 1, b: 2, c: 3, d: 4};

var newObject = R.filter(R.props('a'), myObject);
//var newObject = R.filter(R.equals(R.props('a')), myObject);

console.log('newObject', newObject);

现在上面的代码返回整个对象:

newObject {"a":1,"b":2,"c":3,"d":4}

我想做的只是返回一个只有'a'键的新对象。或者使用ab键的新对象。

3 个答案:

答案 0 :(得分:13)

使用pick

let newObj = R.pick(['a'], oldObj);

如果您的过滤条件比仅存在更复杂,您可以使用pickBy通过任意谓词函数进行选择。

答案 1 :(得分:6)

杰瑞德史密斯的答案很棒。我只想添加一个说明为什么你的代码不起作用的说明。你试过

R.filter(R.props('a'), {a: 1, b: 2, c: 3, d: 4});

首先,您指出了prop的文档,但使用了props。这些是不同但相关的功能。 prop看起来像

// prop :: k -> {k: v} -> v
prop('c', {a: 1, b: 2, c: 3, d: 4}); //=> 3

undefined会增加一些复杂性。)

另一方面,

props需要多个值

// props :: [k] -> {k: v} -> [v]
props(['a', 'd'], {a: 1, b: 2, c: 3, d: 4}); //=> [1, 4]

但这些都不会成为filter的有用输入,为了这些目的,我们可以将其视为

// filter :: (k -> Bool) -> {k: v} -> {k: v}

filter的第一个参数是从(字符串)键到布尔值的函数;它适用于Javascript的想法,除了一些特定的值,一切都是真实的。它将依次用每个键调用。例如,在决定是否包含{c: 3}时,它会调用props('a')('c'),这是另一个有点奇怪的原因 * ,实际上有效,返回[3],这是被视为真实y,过滤函数将在其输出中包含{c: 3}。所以每一把钥匙都会被包括在内。

* props('a', obj)真正应该是props(['a'], obj)时的原因是JS中的字符串足够接近列表,具有length属性,索引值。 'a'.length; ==> 1'a'[0]; //=> 'a'。因此props可以将单字符字符串视为字符串的单元素列表。但它也可能有点奇怪:R.props('cabby', {a: 1, b: 2, c: 3, d: 4}); //=> [3, 1, 2, 2, undefined]

答案 2 :(得分:2)

pickBy

const getOnlyGoods = R.pickBy((_, key) => key.includes('good'));

const onlyGoods = getOnlyGoods({
  "very good":    90,
  "good":         80,
  "good enough":  60,
  "average":      50,
  "bad":          30,
  "?":           10,
});

console.log(onlyGoods);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>