【问题标题】:How to modify a subset of data without using variables如何在不使用变量的情况下修改数据子集
【发布时间】:2016-09-17 15:11:00
【问题描述】:

如果我有一些像这样的(半准确的)数据,请使用函数式 Javascript,如 UnderscoreLodhashRamdaImmutable JS

var data = {
  people: [
    {name: 'Vishwanathan Anand', age: 46},
    {name: 'Garry Kasparov', age: 52},
    {name: 'Magnus Carlsen', age: 25},
  ],
  computers: [
    {name: 'Deep Blue', age: 26},
    {name: 'Deep Fritz', age: 21},
    {name: 'Deep Thought', age: 28},
  ]
}

我想把它改成

var data = {
  people: [
    {name: 'Vishwanathan Anand', age: 46, rank: 0},
    {name: 'Garry Kasparov', age: 52, rank: 1},
    {name: 'Magnus Carlsen', age: 25, rank 2},
  ],
  computers: [
    {name: 'Deep Blue', age: 26},
    {name: 'Deep Fritz', age: 21},
    {name: 'Deep Thought', age: 28},
  ]
}

注意只有people 子结构是如何得到rank的。

我知道我可以,

_.extend({
  computers: _.map(data.people, (p, i) => {
    p.rank = i;
    return p;
  })}, {
    computers: data.computers
  })

但是如果我需要在不使用任何变量的情况下使用下划线的chain 来执行此操作(不再访问data!)怎么办?

类似

_.chain(data).subset('people').map((p, i) => {
  p.rank = i;
  return p;
})

注意 这是一个真正的问题,而不是为了方便。我正在开展一个项目,该项目涉及为功能运算符创建一种环境,并且不允许使用 变量

似乎Underscore等对整个结构(数组/列表)进行操作。有什么方法可以要求它在一个子结构上运行,同时保留其余部分?

【问题讨论】:

  • _.each(data.people, (p,i)=>{ p.rank=i }) 怎么样。但那是突变,这在函数式编程中是非常非常邪恶的;)
  • @Thomas 完全正确!该函数不再是纯粹的。对于更复杂的示例,如果没有each,我们如何做到这一点?
  • “不允许使用变量”并没有多大意义。没有变量,你甚至不能使用函数,没有函数,你什么也做不了。
  • 我想你要找的是镜头。
  • 我猜应该是propertyLens("people")(ps => ps.map((p, i) => (p.rank=i,p)))(data)

标签: javascript functional-programming underscore.js lodash ramda.js


【解决方案1】:

这个解决方案有点令人不快,但它适用于这种情况。

_.chain(data)
    .mapObject((value, key) => {
        if (key==='people') {
            return value.map((p,i) => _.extend(p, {rank: i}));
        } else {
            return value;
        }
    })
    .value();

【讨论】:

    【解决方案2】:

    使用 Ramda,您可以使用 R.evolve 创建一个函数,该函数接受一个键和一个回调 (cb),并将键的项目映射到所需的形式:

    const { evolve, addIndex, map } = R
    
    const mapPart = (cb, key) => evolve({
      [key]: addIndex(map)(cb)
    })
    
    const data = {"people":[{"name":"Vishwanathan Anand","age":46},{"name":"Garry Kasparov","age":52},{"name":"Magnus Carlsen","age":25}],"computers":[{"name":"Deep Blue","age":26},{"name":"Deep Fritz","age":21},{"name":"Deep Thought","age":28}]}
    
    const result = mapPart((o, rank) => ({ ...o, rank }), 'people')(data)
    
    console.log(result)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

    【讨论】:

      猜你喜欢
      • 2016-08-13
      • 2020-02-01
      • 2022-07-12
      • 2022-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多