4

给定一个如下所示的旋转函数,它将数组旋转一定数量的槽。

是否有等效的 Ramda.js 函数或组合可以执行此轮换?

var test = [1,2,3,4,5,6,7,8,9];
function rotate(arr, count) {
    arr = arr.slice();
    while (count < 0) {
      count += arr.length;
    }
    count %= arr.length;
    if (count) {
      arr.splice.apply(arr, [0, 0].concat([].slice.call(arr.splice(arr.length - count, count))));
    }
    return arr;
}

例子

rotate(test, 2) // -> [8, 9, 1, 2, 3, 4, 5, 6, 7]
4

3 回答 3

2

这是一个无点的单列,它首先计算计数,然后计算数据,与 ramda 的可组合风格一致:

const rotate = pipe(splitAt, reverse, flatten);

当然,您始终flip(rotate)可以获取数据的第一个版本。

更新

对不起,我读得太快了,假设旋转的方向是正常的,向左的方向(例如,在红宝石中)。这是您原来所做的想法的变体:

const rotate = pipe(useWith(splitAt, [negate, identity]), reverse, flatten);
于 2016-11-15T04:48:29.660 回答
1

这类似于@donnut 的答案,但包括模运算来处理超过给定列表长度的计数:

var rotate2 = function(xs, count) {
  var n = -(count % xs.length);
  return R.concat(R.slice(n, Infinity, xs),
                  R.slice(0, n, xs));
};

这是一个完全不使用 Ramda 的无突变等价物:

var rotate3 = function(xs, count) {
  var n = -(count % xs.length);
  return xs.slice(n).concat(xs.slice(0, n));
};

这两种解决方案都比原始帖子中的解决方案更具声明性。

于 2015-06-04T14:42:25.130 回答
0

你可以试试:

function reverse(arr, count) {
    return R.concat(R.slice(arr.length-count, arr.length, arr),  R.slice(0, arr.length-count, arr));
}

http://bit.ly/1G90ny8

于 2015-06-04T13:51:06.250 回答