nor*_*tpy 2 javascript functional-programming
我怎么能只使用map,reduce或filter或者创建一个阵列上的自定义迭代任何功能性的方式?
假设我想将一个数组映射到另一个数组,该数组包含源数组中每三个相邻元素的总和:
var source = [1, 2, 3, 4, 6, 7, 8] // to [6, 17, 8]
Run Code Online (Sandbox Code Playgroud)
或者制作一个包含两个元素的桶:
var source = [1, 2, 3, 4, 5, 6, 7] // to [[1, 2], [3, 4], [5, 6], [7]]
Run Code Online (Sandbox Code Playgroud)
对于第二个,我有以下但是看起来不是很有用,因为我正在通过索引访问数组:
function* pairMap(data) {
yield* data.map((item, index) => {
if (index > 0) {
return [data[index - 1], item];
}
});
}
Run Code Online (Sandbox Code Playgroud)
我对这样做的功能方式很感兴趣.
Tha*_*you 10
假设我想将一个数组映射到另一个数组,该数组包含源数组中每三个相邻元素的总和:
Run Code Online (Sandbox Code Playgroud)var source = [1, 2, 3, 4, 6, 7, 8] // to [6, 17, 8]
地图创建1:1关系,因此这不适合使用map.相反,a reduce或("折叠")在这里会更好.
const comp = f=> g=> x=> f (g (x));
const len = xs=> xs.length;
const isEmpty = xs=> len(xs) === 0;
const concat = xs=> ys=> ys.concat(xs);
const chunk= n=> xs=>
isEmpty (xs)
? []
: concat (chunk (n) (xs.slice(n))) ([xs.slice(0,n)]);
const reduce = f=> y=> xs=> xs.reduce((y,x)=> f(y)(x), y);
const map = f=> xs=> xs.map(x=> f(x));
const add = x=> y=> y + x;
const sum = reduce (add) (0);
var source = [1, 2, 3, 4, 6, 7, 8];
comp (map (sum)) (chunk (3)) (source);
//=> [ 6, 17, 8 ]
Run Code Online (Sandbox Code Playgroud)
所以你可以看到,我们首先将变换source为3的块,然后我们map将sum每个块的函数转换为块.
当你听到人们谈论"声明性"代码时,最后一行很清楚,并且对实现几乎不担心.我们没有告诉计算机如何完成它的工作.没有for/ while循环,没有无关的变量或迭代器,没有逻辑等.
"idgaf如何,只需source分成3组,然后将每个部分相加"
// very declaration, wow
comp (map (sum)) (chunk (3)) (source);
Run Code Online (Sandbox Code Playgroud)
或者制作一个包含两个元素的桶:
Run Code Online (Sandbox Code Playgroud)var source = [1, 2, 3, 4, 5, 6, 7] // to [[1, 2], [3, 4], [5, 6], [7]]
使用上面相同的代码
var source = [1, 2, 3, 4, 5, 6, 7];
chunk (2) (source);
// => [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ], [ 7 ] ]
Run Code Online (Sandbox Code Playgroud)
对于第二个,我有以下但是看起来不是很有用,因为我正在通过索引访问数组:
Run Code Online (Sandbox Code Playgroud)function* pairMap(data) { yield* data.map((item, index) => { if (index > 0) { return [data[index - 1], item]; } }); }
使用上面的代码,您可以pairMap轻松实现
const pairMap = f=> comp (map (f)) (chunk (2));
var source = [1, 2, 3, 4, 5, 6, 7];
pairMap (pair => console.log(pair)) (source);
// [ 1, 2 ]
// [ 3, 4 ]
// [ 5, 6 ]
// [ 7 ]
Run Code Online (Sandbox Code Playgroud)
了解所有事情
问题是"自定义迭代的功能方式".您会注意到我的代码使用Array.prototype.reduce和排序作弊Array.prototype.map.学习如何自己构建这些是一个很好的学习工具,让我理解构建功能循环/迭代器/控件很有趣而且简单
const isEmpty = xs=> xs.length === 0
const head = xs=> xs[0];
const tail = xs=> xs.slice(1);
const reduce = f=> y=> xs=>
isEmpty (xs)
? y
: reduce (f) (f (y) (head (xs))) (tail (xs));
const add = x=> y=> y + x;
reduce (add) (0) ([1,2,3]);
//=> 6
Run Code Online (Sandbox Code Playgroud)
有用!.
好的,让我们看看我们如何做地图
const concat = xs=> ys=> ys.concat(xs);
const append = x=> concat ([x]);
const map = f=>
reduce (ys=> x=> append (f (x)) (ys)) ([]);
const sq = x => x * x;
map (sq) ([1,2,3])
//=> [ 1, 4, 9 ]
Run Code Online (Sandbox Code Playgroud)
测验1:你会写filter,some和every使用reduce?
巨魔警告:实现这些功能的方法有很多种.如果你开始编写递归函数,你首先想要了解的是尾调用.ES6正在进行尾部呼叫优化,但它暂时不会普及.有一段时间,Babel可以使用while循环来转换它,但它在版本6中暂时禁用,并且一旦修复就会回来.
测验2:你怎么能用reduce正确的尾调来改写我?