使用 Ramda 增加映射数组中的数字
Increment numbers in mapped array using Ramda
我有一个如下所示的数组:
[{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 中,我尝试在映射数组时添加之前的距离值,但它不起作用,因为它未定义。我也研究过 reduce 但没有成功。关于如何在 Ramda.js 中完成此操作的任何想法?
尽管我很喜欢 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;
}, []);
尝试以下方法
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
将包含您想要的数组。
查看快照:
如果您想在这里使用 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>
或者您可以使用 scan
:
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))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
这不适用于空列表。如果这是一个问题,我们可以通过跳过 lift(...)(head, tail)
并仅使用具有初始值的 scan
,然后采用 tail
来改变它。但如果这不是问题,这段代码会更清晰。
我有一个如下所示的数组:
[{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 中,我尝试在映射数组时添加之前的距离值,但它不起作用,因为它未定义。我也研究过 reduce 但没有成功。关于如何在 Ramda.js 中完成此操作的任何想法?
尽管我很喜欢 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;
}, []);
尝试以下方法
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
将包含您想要的数组。
查看快照:
如果您想在这里使用 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>
或者您可以使用 scan
:
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))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
这不适用于空列表。如果这是一个问题,我们可以通过跳过 lift(...)(head, tail)
并仅使用具有初始值的 scan
,然后采用 tail
来改变它。但如果这不是问题,这段代码会更清晰。