使用Ramda增加映射数组中的数字

时间:2017-12-19 19:43:15

标签: javascript ramda.js

我有一个如下所示的数组:

[{location: {…}, distance: 0}
{location: {…}, distance: 0}
{location: {…}, distance: 0.37348441209694133}
{location: {…}, distance: 0}
{location: {…}, distance: 0.4229382782128456}
{location: {…}, distance: 0}
{location: {…}, distance: 0.006098292961396555}
{location: {…}, distance: 0}
{location: {…}, distance: 0.07885846317546494}]

我想映射一个新数组,其距离值从前一个值开始递增。因此,在上面的示例中,最后一个距离值将为0.88137944644665,因为它在迭代所有对象时添加了所有值。

在Ramda.js中,当我映射数组时,我尝试添加前一个距离值,但由于它未定义,因此无法正常工作。我也考虑过减少而没有成功。关于如何在Ramda.js中实现这一点的任何想法?

4 个答案:

答案 0 :(得分:4)

就像我爱Ramda一样,你不需要它:

arr.map(({ location, distance }) => ({ location, distance: distance + 1 }));

要打破这一点:

arr // your array of objects
  .map( // call to Array.prototype.map
    ({ location, distance }, i, arr) => // function params, destructures
      ({ location, distance: distance + 1 })); // return new object same loc, incremented distance

修改

由于我错过了有关聚合的部分,请使用reduce代替:

arr.reduce((aggregate, { location, distance }, i) => {
  const dist = i ? aggregate[i - 1].distance : 0;
  aggregate.push({ location, distance: distance + dist });
  return aggregate;
}, []);  

答案 1 :(得分:2)

尝试以下

const reducedData = data.reduce( (prev, val) => {
  prev.sum += val.distance
  prev.datas.push({
    ...val,
    distance: prev.sum
  })
  return prev;
}, {sum: 0, datas: []})

数据上的.reduce循环并将每行合并到prev。此脚本的最终输出是一个看起来像{ sum: number , datas: [...]}的对象,sum这里是总距离,datas将包含您想要的数组。

查看快照:enter image description here

答案 2 :(得分:2)

如果您正在寻找使用Ramda函数,R.scan可以提供帮助。此函数与reduce非常相似,但它不会返回单个汇总值,而是生成每个连续结果的列表。



const distanceL = R.lensProp('distance')
const addDistance = R.compose(R.add, R.prop('distance'))
const fn = data =>
  R.scan(
    (acc, next) => R.over(distanceL, addDistance(acc), next),
    data[0],
    R.tail(data)
  )

console.log(fn([
  {location: {}, distance: 0},
  {location: {}, distance: 0},
  {location: {}, distance: 0.37348441209694133},
  {location: {}, distance: 0},
  {location: {}, distance: 0.4229382782128456},
  {location: {}, distance: 0},
  {location: {}, distance: 0.006098292961396555},
  {location: {}, distance: 0},
  {location: {}, distance: 0.07885846317546494}
]))

<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
&#13;
&#13;
&#13;

答案 3 :(得分:1)

或者您可以使用scan

&#13;
&#13;
const {lift, scan, head, tail} = R

const xs = [
  {location: {id: 1}, distance: 0},
  {location: {id: 2}, distance: 0},
  {location: {id: 3}, distance: 0.37348441209694133},
  {location: {id: 4}, distance: 0},
  {location: {id: 5}, distance: 0.4229382782128456},
  {location: {id: 6}, distance: 0},
  {location: {id: 7}, distance: 0.006098292961396555},
  {location: {id: 8}, distance: 0},
  {location: {id: 9}, distance: 0.07885846317546494}
]

const accumDist = lift(scan((agg, x) => ({...x, distance: x.distance + agg.distance})))(head, tail)

console.log(accumDist(xs))
&#13;
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
&#13;
&#13;
&#13;

这不会使用空列表。如果这是一个问题,我们可以通过跳过lift(...)(head, tail)并使用带有初始值的scan然后取tail来改变它。但如果这不是问题,那么这段代码就更清晰了。