我正在研究如何在JavaScript中使用生成器。
由于生成器返回迭代器,我想我可以像iterable.filter()
那样使用array.prototype.filter
。
但是,iterable对象没有filter,map,forEach,reduce方法。
所以,我做了一个生成器版本的filter,map,reduce,forEach方法,如下所示。
'use strict';
function* range(n) {
for (let i = 1; i <= n; i++) {
yield i;
}
}
function* filter(context, predicate) {
for (let i of context) {
if (predicate(i) === true) {
yield i;
}
}
}
function isEven(value) {
return value % 2 === 0;
}
console.log(
...filter(range(10), isEven)
);
此代码确实有效,但我希望filter(range(10), isEven)
使用range(10).filter(isEven)
而不是range(10)
.filter(isEven) //generator version of filter
.map(multiplyBy5) //generator version of map
.forEach(console.log); //generator version of forEach
。
有没有办法达到我的目的?
我正在研究ES6代理,反思,但是嗯......我不确定这些ES6是否能帮助我。
'use strict';
function* filter(predicate) {
for (let i of this) {
if(predicate(i) === true) {
yield i;
}
}
}
function* map(project) {
for (let i of this) {
yield project(i);
}
}
function* range(end) {
for (let i = 0; i <= end; i++) {
yield i;
}
}
const isEven = (v) => v % 2 === 0;
const multiplyBy = (v) => (by) => v * by;
var range10_filterByEven = filter.bind(range(10), isEven);
var range10_filterByEven_multiplyBy10 = map.bind(range10_filterByEven(), multiplyBy(10));
console.log(
...range10_filterByEven_multiplyBy10() //0 20 40 60 80 100
);
此代码也有效,但这就像一个笑话......
'use strict';
function filter(predicate) {
return function* f() {
for (let i of this) {
if(predicate(i) === true) {
yield i;
}
}
}
}
function map(project) {
return function* m() {
for (let i of this) {
yield project(i);
}
}
}
function range(end) {
return function* r() {
for (let i = 0; i <= end; i++) {
yield i;
}
}
}
const isEven = (v) => v % 2 === 0;
const multiplyBy = (v) => (by) => v * by;
function pipe() {
return [...arguments].reduce(function(chain, current) {
return current.bind(chain());
})}
console.log(
...pipe(
range(10),
filter(isEven),
map(multiplyBy(10))
)()
);
@GetMapping("/image/{name:.+}")
public byte[] getImage(@PathVariable(value = "name") String name) {
return storageService.loadFileAsByteArray(name);
}
答案 0 :(得分:1)
你可能只是扩展生成器原型,虽然这看起来很糟糕,我不确定我会推荐这种方法。
另一方面,我相信这是你所期望的最简单的方法。
function* range(n) {
for (let i = 1; i <= n; i++) {
yield i;
}
}
// "Generator" is not resolvable at the top level
var Generator = Object.getPrototypeOf(function* () {});
Generator.prototype.filter = function*(predicate) {
for (let i of this) {
if (predicate(i) === true) {
yield i;
}
}
}
for ( var elem of range(10).filter( x => x<5) ) {
console.log(elem);
}
for ( var elem of range(10).filter( x => x<5 ).filter( x => x<3 ) ) {
console.log(elem);
}
其他运营商可能会以类似的方式添加。