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

17

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

Ramda Repl

(注:这段内容是两个链接,第一个链接是 Ramda.js 的文档,第二个链接是一个在线工具 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键。


1
你想要一个只包含你所需键的对象吗? - Jared Smith
4个回答

21

使用pick函数:

let newObj = R.pick(['a'], oldObj);
如果您的筛选条件比仅仅是存在更加复杂,您可以使用pickBy通过任意谓词函数进行选择。

10

Jared Smith的回答很好。我只想补充一下为什么你的代码没有起作用。你尝试了

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],这被视为真值,过滤函数将在其输出中包含 {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]


5

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>


1

除了其他答案之外,还有omit可以过滤掉特定的属性。

omit(["a"], { a: 1, b: 2 }) // -> { b: 2 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接