Javascript 以函数方式使用两个相邻元素进行列表遍历
我正在尝试实现下面代码的功能版本Javascript 以函数方式使用两个相邻元素进行列表遍历,javascript,functional-programming,ramda.js,Javascript,Functional Programming,Ramda.js,我正在尝试实现下面代码的功能版本 const adjacent = (list) => { let results = []; for (let idx = 0; idx < list.length - 1; idx++) { const computedRes = someComplexFn(list[idx], list[idx + 1]); results.push(computedRes ); } return re
const adjacent = (list) => {
let results = [];
for (let idx = 0; idx < list.length - 1; idx++) {
const computedRes = someComplexFn(list[idx], list[idx + 1]);
results.push(computedRes );
}
return results;
}
const相邻=(列表)=>{
让结果=[];
for(让idx=0;idx
我提供了以下版本
const locations = [1,2,3,4,5];
const calcRatioFn = (x, y) => x+y;
const adjacentMap = (list, result=[]) => {
if(R.length(list) < 2) {
return result;
}
const f1 = R.head(list);
const f2 = R.tail(list);
result.push(calcRatioFn(f1 ,R.head(f2)));
return adjacentMap(R.tail(list), result);
}
const results = adjacentMap(locations);
console.log(results);
const locations=[1,2,3,4,5];
常数calcRatioFn=(x,y)=>x+y;
常量邻接映射=(列表,结果=[])=>{
如果(R.长度(列表)<2){
返回结果;
}
常数f1=右端头(列表);
常数f2=R.tail(列表);
结果:推挤(calcRatioFn(f1,右头部(f2));
返回邻接图(R.tail(list),结果);
}
常量结果=邻接地图(位置);
控制台日志(结果);
上述问题还有其他简单的解决方案吗
我们是否可以避免使用上述函数中的默认结果值参数和if条件检查
JSBin链接
一种方法是使用创建相邻元素的滑动窗口。然后,为了获得一点额外的糖分,可以包装someComplexFn,将二进制函数转换为一个接受两个元素数组的函数 您的示例将如下所示:
const adjacentMap = R.pipe(R.aperture(2), (R.map(R.apply(someComplexFn))))
一种方法是使用创建相邻图元的滑动窗口。然后,为了获得一点额外的糖分,可以包装someComplexFn,将二进制函数转换为一个接受两个元素数组的函数 您的示例将如下所示:
const adjacentMap = R.pipe(R.aperture(2), (R.map(R.apply(someComplexFn))))
另一种方法是在没有最后一个元素的数组和没有第一个元素的数组上使用
converge
let locations = [1,2,3,4,5];
const calcRatio = (x, y) => x+y;
// adjacentMap :: Array -> Array
const adjacentMap = R.converge(
R.zipWith(calcRatio),
[ R.init, R.tail]
);
// saveAdjacentMap :: Array -> Array
const saveAdjacentMap = R.cond([
[R.compose(R.lt(1), R.length), adjacentMap ],
[R.T, R.identity]
]);
console.log(saveAdjacentMap(locations));
您的JSBin使用Ramda0.8.0。在当前版本
0.24.1
中,情况发生了变化。另一种方法是在不带最后一个元素的数组和不带第一个元素的数组上使用converge
let locations = [1,2,3,4,5];
const calcRatio = (x, y) => x+y;
// adjacentMap :: Array -> Array
const adjacentMap = R.converge(
R.zipWith(calcRatio),
[ R.init, R.tail]
);
// saveAdjacentMap :: Array -> Array
const saveAdjacentMap = R.cond([
[R.compose(R.lt(1), R.length), adjacentMap ],
[R.T, R.identity]
]);
console.log(saveAdjacentMap(locations));
您的JSBin使用Ramda0.8.0。在当前版本
0.24.1
中,情况发生了变化。以下代码可能是您所需要的,或者可以根据您所需的解决方案进行调整
const fn = (acc, c, i, a) => {
return !(a[i + 1])
? acc
: acc.concat(c + a[i + 1])
}
const _adjacentMap = (fn, list) => {
return list.reduce(fn, [])
}
const locations = [1,2,3,4,5]
const result = _adjacentMap(fn, locations)
console.log(result)
// => [ 3, 5, 7, 9 ]
下面的代码可能是您所需要的,也可能适合您所需的解决方案
const fn = (acc, c, i, a) => {
return !(a[i + 1])
? acc
: acc.concat(c + a[i + 1])
}
const _adjacentMap = (fn, list) => {
return list.reduce(fn, [])
}
const locations = [1,2,3,4,5]
const result = _adjacentMap(fn, locations)
console.log(result)
// => [ 3, 5, 7, 9 ]
典型的解决方案是使用
drop
+zip
,典型的解决方案是使用drop
+zip
。0或1个元素的边缘大小写如何?@vito传入一个包含0或1个元素的列表将导致一个空列表。你有没有想过一个不同的结果?谢谢你优雅的解决方案。0或1个元素的边缘大小写如何?@vito传入一个包含0或1个元素的列表将导致一个空列表。你有没有想过一个不同的结果?