按(唯一)匹配值过滤

Filter by (unique) matching values

使用 Ramda 和

const data = [{
  "id": "a",
  "name": "A"
}, {
  "id": "b",
  "name": "B"
}, {
  "id": "c",
  "name": "C"
}]

我可以

const findById = (id, data) => R.pipe(
  R.find(R.propEq('id', id))
)(data)

const id = "a"

findById(id, data) // => { "id": "a", "name": "A" }

但是如何将一个 id 值数组 return 一个只包含匹配对象的列表呢?即

const ids = ["a", "c"]

const findByIds = (ids, data) => R.pipe(
  // ?
)(data)

findByIds(ids, data) // => [{"id": "a", "name": "A"}, {"id": "c", "name": "C"}]

类似于 pluck、pick 等,但用于值而不是键,其中每个值都可以假定为唯一。

(更喜欢简洁,甚至可能是无点变体)。

到目前为止,我最接近的是交换 ?对于

  R.filter(x => R.contains(x.id, ids))

  R.takeWhile(x => R.contains(x.id, ids))

两者都生成 A 对象。

谢谢!我是 Ramda 的新手,以上内容主要是我如何使用它,所以任何有关这方面的见解也将非常受欢迎。

更新

这不是问题。它实际上在 REPL 中有效,但不适用于我本地环境(Atom + Wallaby + AVA)中的测试。不知道为什么,但如果我弄明白了,我会更新。使用静态和动态密钥查看变体的验证答案。听到任何其他方法仍然很有趣。

更新 2

原来这只是一个错字。也许我应该重新考虑对测试 ID 使用复杂的哈希值。 :D

(Preferring terse, maybe even point-free variants).

这是错误的objective。更喜欢可读性强且有效的代码。编码不是最短答案获胜的游戏,除非 coding is a game where the shortest answer wins。如果你想要 "golfed" 代码,你应该在那里问。

不管怎样,你自己已经给出了答案。

var data = [{
  "id": "a",
  "name": "A"
}, {
  "id": "b",
  "name": "B"
}, {
  "id": "c",
  "name": "C"
}];

const findByIds = R.curry((ids, data)=>
  R.filter(x=> R.contains(x.id, ids), data));

findByIds (['a', 'c']) (data);
//=> [{"id": "a", "name": "A"}, {"id": "c", "name": "C"}]

也许您希望 "id" 是动态的 属性

var data = [{
  "id": "a",
  "name": "A"
}, {
  "id": "b",
  "name": "B"
}, {
  "id": "c",
  "name": "C"
}];

const findByProp = R.curry((prop, ids, data) =>
  R.filter(x=> R.contains(x[prop], ids), data));

findByProp ('id', ['a', 'c'], data);
//=> [{"id": "a", "name": "A"}, {"id": "c", "name": "C"}]