JavaScript 中 Ruby 的 each_cons 的等价物
Equivalent of Ruby's each_cons in JavaScript
很多语言都问过这个问题,但 javascript。
Ruby 的方法 Enumerable#each_cons
看起来像这样:
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]]
如何在 javascript 中为 Array
使用类似的方法?
下面是一个函数(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))
你必须猜测结果数组的长度(n = length - num + 1
),然后你可以利用JavaScript的array.slice
来得到你需要的块,迭代n
次。
这是一个依赖于函数生成器的单行解决方案。可能略有不同,但仍然值得一试。
我也添加到原型中,不知道你为什么要那样做,但仍然..
这个解决方案不需要ES6,它也可以与ES5一起使用,对完全不支持函数生成器的IE有点照顾。
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);
}
您可以获取长度,构建一个新数组并使用 Array.from
和内置映射器映射切片数组。
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; }
很多语言都问过这个问题,但 javascript。
Ruby 的方法 Enumerable#each_cons
看起来像这样:
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]]
如何在 javascript 中为 Array
使用类似的方法?
下面是一个函数(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))
你必须猜测结果数组的长度(n = length - num + 1
),然后你可以利用JavaScript的array.slice
来得到你需要的块,迭代n
次。
这是一个依赖于函数生成器的单行解决方案。可能略有不同,但仍然值得一试。
我也添加到原型中,不知道你为什么要那样做,但仍然..
这个解决方案不需要ES6,它也可以与ES5一起使用,对完全不支持函数生成器的IE有点照顾。
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);
}
您可以获取长度,构建一个新数组并使用 Array.from
和内置映射器映射切片数组。
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; }