最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

arrays - Equivalent of Ruby's each_cons in JavaScript - Stack Overflow

programmeradmin2浏览0评论

The question has been asked for many languages, yet not for javascript.

Ruby has the method Enumerable#each_cons which look like that:

puts (0..5).each_cons(2).to_a
# [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5]]
puts (0..5).each_cons(3).to_a
# [[1, 2, 3], [2, 3, 4], [3, 4, 5]]

How could I have a similar method in javascript for Array?

The question has been asked for many languages, yet not for javascript.

Ruby has the method Enumerable#each_cons which look like that:

puts (0..5).each_cons(2).to_a
# [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5]]
puts (0..5).each_cons(3).to_a
# [[1, 2, 3], [2, 3, 4], [3, 4, 5]]

How could I have a similar method in javascript for Array?

Share Improve this question edited Aug 13, 2019 at 13:36 Ulysse BN asked Aug 13, 2019 at 12:39 Ulysse BNUlysse BN 11.5k7 gold badges62 silver badges93 bronze badges 0
Add a ment  | 

3 Answers 3

Reset to default 7

Here is a function that will do it (ES6+):

// functional approach
const eachCons = (array, num) => {
    return Array.from({ length: array.length - num + 1 },
                      (_, i) => array.slice(i, i + num))
}

// prototype overriding approach
Array.prototype.eachCons = function(num) {
  return Array.from({ length: this.length - num + 1 },
                    (_, i) => this.slice(i, i + num))
}


const array = [0,1,2,3,4,5]
const log = data => console.log(JSON.stringify(data))

log(eachCons(array, 2))
log(eachCons(array, 3))

log(array.eachCons(2))
log(array.eachCons(3))

You have to guess the length of the resulting array (n = length - num + 1), and then you can take advantage of JavaScript's array.slice To get the chunks you need, iterating n times.

You could take the length, build a new array and map the sliced array with Array.from and the build in mapper.

Number.prototype[Symbol.iterator] = function* () {
    for (var i = 0; i < this; i++) yield i;
};

Array.prototype.eachCons = function (n) {
    return Array.from({ length: this.length - n + 1}, (_, i) => this.slice(i, i + n));
}

console.log([...10].eachCons(2));
console.log([...10].eachCons(3));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Here is a single line solution relying on function generators. Perhaps slightly different, but still worth to try out.

I've also added to the prototype, not sure why you would do that, but still..

This solution doesn't require ES6, it can be used with ES5 as well, with a bit of care for IE that doesn't support function generators at all.

function* eachCons(arr, num) {
  for (let counter = 0; counter <= arr.length - num; counter++) yield arr.slice(counter, counter + num);
}

Array.prototype.eachCons = function* (num) {
  for (let counter = 0; counter <= this.length - num; counter++) yield this.slice(counter, counter + num);
}

const array = [0,1,2,3,4,5];
const log = data => console.log(JSON.stringify(data))
log([...eachCons(array, 2)]);
log([...eachCons(array, 3)]);

// Iterable way
for (let [...pack] of eachCons(array, 2)) {
  console.log('pack is', pack);
}
// Prototype...
for (let [...pack] of array.eachCons(2)) {
  console.log('pack is', pack);
}

发布评论

评论列表(0)

  1. 暂无评论