Equivalent of Ruby's each cons in JavaScript

JavascriptWeb DevelopmentObject Oriented Programming

each_cons() - Ruby

The each_cons() method of enumerable is an inbuilt method in Ruby that iterates for consecutive N elements starting from each element every time. If no block is given, it returns the enumerator.

JS equivalent of each_cons()

Suppose we have an array of Number literals (JS equivalent of Ruby’s enumerable in this case), the each_cons function is supposed to be an Array function that executes for each element of the array and accepts a number N (N <= length of array) as only argument. And returns an array with subarrays of size N with each subarray starting from all elements one by one.

An example of this would make things a bit clearer.

Suppose we have an array like this −

const arr = [1, 2, 3, 4, 5];
console.log(arr.eachCons(2));

What this call to eachCons does is that, it forms an array of arrays with 2 elements each like this −

[[1, 2], [2, 3], [3, 4], [4, 5]]

Notice that the subarrays are created for each element of the original array until we can do so.

Had the value of N been 3 instead of 2, the result would have looked like −

[[1, 2, 3], [2, 3, 4], [3, 4, 5]]

Again, subarrays are created for every element of the array until we have enough elements in the array.

Approach

We will be using the sliding window algorithm to solve this problem.

Although we can use the modern ES6 functions to solve this in two lines, but the former approach is very efficient as compared to the latter.

Firstly, we will utilise a while loop that creates our initial window from 0 to N index. Then. we will use a for loop which runs while the end of our window is still less than the length of the original array.

This loop checks for the stability of our window (i.e., the length of our window being equal to N). If the window is stable, we insert the window (that subarray into the results array), slide it to the right by unit distance and collapse it (i.e., start = end). If the window is unstable, we keep adding elements to it.

The code for this approach is −

Example

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

Output

The output in the console will be −

[ [ 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 ] ]
raja
Published on 25-Aug-2020 06:17:57
Advertisements