以功能方式列出具有两个相邻元素的遍历

时间:2017-09-30 05:20:44

标签: 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 results;
  }

我来的是以下版本

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

上述任何其他简单的解决方案吗?

我们可以避免使用默认结果值参数吗?如果从上面的函数中检查条件吗?

JSBin Link http://jsbin.com/veyihepulu/1/edit?html,js,console

3 个答案:

答案 0 :(得分:3)

一种方法是使用R.aperture创建相邻元素的滑动窗口。然后为了一些额外的糖someComplexFn可以用R.apply包裹,将二进制函数转换成一个接受两个元素数组的函数。

您的示例将如下所示:

const adjacentMap = R.pipe(R.aperture(2), (R.map(R.apply(someComplexFn))))

答案 1 :(得分:0)

另一种方法是在没有最后一个元素的数组上使用class UserSeenPosts(models.Model): user = models.ForeignKey(User, related_name='seen_posts') post = models.ForeignKey(Post) ,而在没有第一个元素的情况下使用数组。

converge

您的JSBin使用Ramda 0.8.0。当前版本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)); 已发生变化。

答案 2 :(得分:0)

以下代码可能是您需要或可以根据您所需的解决方案进行调整的。

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 ]