如何在不使用变量

时间:2016-05-20 11:13:17

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

使用UnderscoreLodhashRamdaImmutable JS这样的功能性Javascript,如果我有这样的(半精确)数据:

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
  })

但是,如果我需要使用下划线data而不使用任何变量(不再访问chain!),那该怎么办?

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

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

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

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

使用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>