无点编程难题

时间:2019-11-06 19:41:52

标签: functional-programming ramda.js

我有一个函数,该函数使用匿名函数编写,该函数将使用与id属性匹配的对象列表来合并ID数组。

const objectsList = [{ id: 1, ... }, { id: 2, ... }]
ids.map(id => R.find(R.propEq('id', id), objectsList))

(我知道以这种方式查找对象是很愚蠢的-效率低下,等等-让我们暂时忽略它。)

因此,我想无限制地执行此操作,但我陷入困境。这是最好的尝试:

ids.map(R.find(R.propEq('id', R.__), objects))

但这不好。我还尝试过翻转参数的顺序并使用compose,但这并没有产生正确的结果:

ids.map(R.compose(R.flip(R.find)(objects), R.propEq('id')))

那也不是个骰子...有什么FP向导会在意帮助那些总是想找出无点编程细微差别的人吗?

更新

感谢你们中回答的人!约定的,无意义的编程不应被迷恋。我主要是想加深我对FP和Ramda工具的理解。我同意所有张贴者的观点,即无优先点编程一定不能优先于可读性。

通过此,我肯定对Ramda有了更多的了解,并希望其他人也能做到。 :-)

3 个答案:

答案 0 :(得分:3)

修改

请注意,此处的某些文本基于使用此版本的另一个答案:innerJoin(useWith(equals, [prop('id'), identity]))。该答案已得到改进,不再使用此技术。但是这些评论本身仍然有意义。


我建议您不要迷恋无点编程,而只能在提高可读性的地方使用它。

我发现来自OriDrori的答案的这种变体更容易阅读:

const extractMatches = R.innerJoin ((o, id) => o.id === id)

const objectsList = [{ id: 1, x: 'a' }, { id: 2, x: 'b' }, { id: 3, x: 'c' }, { id: 4, x: 'd' }, { id: 5, x: 'e' }]
const ids = [1, 2, 4]

console .log (
  extractMatches (objectsList, ids)
)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

即使有一些不使用Ramda重量级且有点不直观的useWith的无点版本,也很难获得比上面的那种单行代码更具可读性。

useWith是在许多Ramda用户仍在使用ES5(甚至是ES3!)时编写的。如今,这对我来说似乎不是一个好选择。它唯一增加的就是无点编写功能,通常会掩盖事物。 (免责声明:我是Ramda的创始人之一,并且是忠实的粉丝,但并不是每个功能都能获得同等的爱!)

答案 1 :(得分:2)

由于R.unary将3个参数传递给回调(值,索引,原始数组),因此您需要使用Array.map()将函数的偶数限制为1。 R.propEq需要3个参数,传递给maps回调的值将填充它们,调用函数,然后R.find获得结果,而不是函数。

const objectsList = [{ id: 1 }, { id: 2 }]
const ids = [2]

const fn = R.unary(R.compose(R.flip(R.find)(objectsList), R.propEq('id')))

const result = ids.map(fn)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

如果要抛弃Array.map()并创建无点功能,则可以使用R.innerJoin。要创建谓词,请使用翻转的R.propEq('id')

const { innerJoin, flip, propEq } = R

const fn = innerJoin(flip(propEq('id')))

const objectsList = [{ id: 1 }, { id: 2 }]
const result = fn(objectsList, [2])
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

答案 2 :(得分:2)

编辑:正如Scott所指出的,我没有仔细阅读此问题。这不是无点样式,我也不认为实现无点样式解决方案不是一个好主意。斯科特(Scott)对奥里·德罗里(Ori Drori)答案的变化对我来说很好

我将重新构建问题:“给出一个对象列表,仅将那些id列入白名单的对象”

给出以下对象:

const objects = [{id: 1, title: 'foo'}, {id: 2, title: 'bar'}];

此白名单:

const whitelist = [2];

那么您可以做:

const inArray = flip(includes);
filter(propSatisfies(inArray(whitelist), 'id'), objects);
//=> [{"id": 2, "title": "bar"}]