each_cons()枚举的方法是在Ruby一个内置的方法,该方法为连续的N个元素迭代从每个元素每次开始。如果没有给出块,则返回枚举数。
假设我们有一个Number文本数组(在这种情况下,JS相当于Ruby的enumerable),那么each_cons函数应该是一个Array函数,该函数对数组的每个元素执行并接受数字N(N <=数组长度)作为唯一的论点。并返回一个数组,数组的大小为N,每个子数组都从所有元素开始。
这样的一个例子会使事情变得更清楚。
假设我们有一个像这样的数组-
const arr = [1, 2, 3, 4, 5]; console.log(arr.eachCons(2));
这个对eachCons的调用的作用是,它形成一个数组数组,每个数组有2个元素,像这样-
[[1, 2], [2, 3], [3, 4], [4, 5]]
注意,直到我们可以为原始数组的每个元素创建子数组。
如果N的值是3而不是2,则结果将看起来像是-
[[1, 2, 3], [2, 3, 4], [3, 4, 5]]
同样,为数组的每个元素创建子数组,直到数组中有足够的元素。
我们将使用滑动窗口算法来解决此问题。
尽管我们可以使用现代的ES6函数在两行中解决此问题,但与后者相比,前一种方法非常有效。
首先,我们将利用while循环来创建从0到N索引的初始窗口。然后。我们将使用一个for循环,该循环将在窗口末尾仍小于原始数组的长度时运行。
此循环检查窗口的稳定性(即,窗口的长度等于N)。如果窗口是稳定的,则将窗口(该子数组插入结果数组),将其向右滑动单位距离并将其折叠(即,start = end)。如果窗口不稳定,我们将继续向其中添加元素。
这种方法的代码是-
const arr = [1, 2, 3, 4, 5]; const eachCons = function(num){ let res = [], temp = []; let start = 0, end = 0; while(end < num){ temp.push(this[end++]); }; for(; end <= this.length ;){ if(temp.length === num){ res.push(temp); start++; end = start; temp = []; } temp[end-start] = this[end]; end++; } return res; }; Array.prototype.eachCons = eachCons; console.log([1, 2, 3, 4, 5].eachCons(1)); console.log([1, 2, 3, 4, 5].eachCons(2)); console.log([1, 2, 3, 4, 5].eachCons(3)); console.log([1, 2, 3, 4, 5].eachCons(4));
输出结果
控制台中的输出将为-
[ [ 1 ], [ 2 ], [ 3 ], [ 4 ], [ 5 ] ] [ [ 1, 2 ], [ 2, 3 ], [ 3, 4 ], [ 4, 5 ] ] [ [ 1, 2, 3 ], [ 2, 3, 4 ], [ 3, 4, 5 ] ] [ [ 1, 2, 3, 4 ], [ 2, 3, 4, 5 ] ]