【问题标题】:Ramda help: Pointfree implementation w/ placeholders to direct argumentsRamda 帮助:使用占位符直接参数的无点实现
【发布时间】:2016-01-16 11:56:07
【问题描述】:

这是我第一次使用 ramda。我正在尝试创建一个映射函数,该函数会自动为数组中的每个对象添加一个键。将有助于反应无状态函数,例如,我们可能有一个带有签名的函数

 ({ prop1, prop2, key }) => ...

还有一个数组

 [{ prop1: 'prop one', prop2: 'prop two' }, {...etc}]

这是一个工作示例:

const mapI = R.addIndex(R.map);
const mapAddIndexedProp = R.curry((key, fn) => mapI(R.pipe(R.flip(R.assoc(key)), fn)));
const mapAddKeyProp = mapAddIndexedProp('key');

但是,鉴于我真正想要的是一个接受字符串和函数的函数,似乎应该有一种方法可以执行以下操作:

const mapAddIndexedProp = mapI(R.pipe(R.flip(R.assoc(<arg1>)), <arg2>));

但我不知道它是如何工作的。任何想法将不胜感激。

或者,很有可能,有一种更简洁的方法可以做到这一点,比如“over”或 transduce。谢谢!

【问题讨论】:

  • 您希望将[{first: 'Alice', last: 'Jones'}, {first: 'Bob', last: 'Smith'}] 之类的列表转换为[{first: 'Alice', last: 'Jones', fullName: 'Alice Jones'}, {first: 'Bob', last: 'Smith', fullName: 'Bob Smith'}] 之类的列表吗?
  • 这可能是最终函数的最终目标,正如@Scott Sauyet 在下面的 addFullNames 中所描述的那样,但其想法是将向对象添加键作为映射变换的一部分和前面将在这个新的 map 函数上调用的函数。仍然不是很清楚,但本质上这将使调用 newMapWithKey(someFn, [{...},{...}]) 成为可能。在我给出的示例中,调用 mapAddKeyProp(someFn, [{...}, {...}]) 会将 [{ key: 0 ...}, { key: 1 ...}] 添加到之前的每个对象传递给 someFn,它可能需要使用该键。

标签: javascript functional-programming currying ramda.js


【解决方案1】:

我认为如果你不坚持让它免积分,这很简单:

const addKey = R.curry((key, fn, vals) => 
    R.map(obj => 
        R.assoc(key, fn(obj), obj), vals));

如果您也确实需要索引,可以将其扩展为:

const addKey2 = R.curry((key, fn, vals) => 
    R.addIndex(R.map)((obj, idx) => 
        R.assoc(key, fn(obj, idx), obj), vals));

你可以这样使用:

const addFullNames = addKey('fullName', person => 
    `${person.first} ${person.last}`
);

const initials = person => R.head(person.first) + R.head(person.last);
const  addIds = addKey2('id', (person, idx) => `${initials(person)}_${idx}`)

var people = [
    {first: 'Wilma', last: 'Flintstone'}, 
    {first: 'Betty', last: 'Rubble'}
];

addFullNames(people); //=>
// [
//     {first: 'Wilma', last: 'Flintstone', fullName: 'Wilma Flintstone'}, 
//     {first: 'Betty', last: 'Rubble', fullName: 'Betty Rubble'}
// ];

addIds(people); //=>
// [
//     {first: 'Wilma', last: 'Flintstone', id: 'WF_0'}, 
//     {first: 'Betty', last: 'Rubble', id: 'BR_1'}
// ];

我确信有一种方法可以让这个分数免费。但我也很确定它的外观会明显不那么优雅。

【讨论】:

  • 是的,这可以解决问题,而且没有管道和翻转,更清洁,这有助于它更接近无点,同时肯定会牺牲可读性。 “无积分”也是我想到的词。谢谢,这实际上是我第一次听到它以及我试图使用该功能。我希望 Ramda 可能有一种方式来规定如何应用参数,(R.__ 和 R.nthArg 的某种组合或其他东西......)在这里实现无积分的理想,但它可能不值得这个案例。谢谢!
  • 如果您还有时间,我认为让这个无意义的答案与您在此处给出的答案有些相似:stackoverflow.com/questions/29617142/…。那里的代码现在执行时出现错误“__arity 的第一个参数必须是不大于 10 的非负整数”。您是否有机会帮助我理解该代码/错误,并可能进一步推动我对无积分实施的愚蠢追求?
  • 这里是我指的代码: // take :: Number -> Object -> Object var take = R.converge( R.pick, R.useWith(R.take, R.身份, R.keys), R.nthArg(1) );
  • 我更新了答案,将recent changes 更改为convergeuseWith,这意味着稍微修改了函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-12
  • 2017-10-07
  • 2018-07-30
  • 2015-04-18
  • 2015-01-15
  • 1970-01-01
相关资源
最近更新 更多