function each(coll, f) {
if (Array.isArray(coll)) {
for (var i = 0; i < coll.length; i++) {
f(coll[i], i);
}
} else {
for (var key in coll) {
f(coll[key], key);
}
}
}
function map(array, f) {
var acc = [];
each(array, function(element, i) {
acc.push(f(element, i));
});
return acc;
}
function max(numbers) {
var maximum = numbers[0];
each(numbers,function(x){
if(x>maximum){
maximum = x;}
});
return maximum;
}
function maximums(arrays){
return map(arrays, function(x){
return max(arrays);
})
}
maximums([1,2,3],[5,6,7])
我不太了解地图。我在每个数组函数中写了一个最大数字,我想实现它来映射。我知道我没有使用return max(数组)返回正确的东西但是我也尝试了返回max(arrays [x])来强调我想要遍历整个数组的参数。 return max(arrays)==&gt; [3,3,3],返回一个数组中最大的数字3次,我也不明白为什么。
答案 0 :(得分:2)
您需要从x
function maximums(arrays) {
return map(arrays, function (x) {
return max(x);
// ^
});
}
使用数组数组调用该函数
maximums([[1, 2, 3], [5, 6, 7]]);
// ^ ^
function each(coll, f) {
if (Array.isArray(coll)) {
for (var i = 0; i < coll.length; i++) {
f(coll[i], i);
}
} else {
for (var key in coll) {
f(coll[key], key);
}
}
}
function map(array, f) {
var acc = [];
each(array, function (element, i) {
acc.push(f(element, i));
});
return acc;
}
function max(numbers) {
var maximum = numbers[0];
each(numbers, function (x) {
if (x > maximum) {
maximum = x;
}
});
return maximum;
}
function maximums(arrays) {
return map(arrays, function (x) {
return max(x);
})
}
console.log(maximums([[1, 2, 3], [5, 6, 7]]));
答案 1 :(得分:2)
您的代码基于错误的构建块(each
),因此其余代码会受到影响。我的回答将以更好的构建块reduce
(又名foldLeft
)开始,并向您展示如何从那里建立起来。
你会注意到这个答案是我们将每个功能分解为非常简单的部分,然后使用higher-order functions将所有内容放在一起。
each
Array.isArray
for
- 使用可变迭代器循环,i
.length
属性我强烈建议您逐步完成对此代码的评估,并了解所有部分的工作原理。如果您能够理解这些程序是如何工作的,那么您将很好地掌握一些最重要的函数式编程基础知识:recursion,immutability,referential transparency ,higher-order functions,currying和function composition †
ES6提供了arrow functions,destructuring assignment和spread syntax,这使得使用JavaScript编写功能性程序变得轻而易举 - 首先,它会让您感觉完全不同。我会在这个片段下方提供ES6之前的版本。
相关: What do multiple arrow functions mean in JavaScript?
// reduce is your new, gold-standard building block
const reduce = f => y => ([x,...xs]) => {
if (x === undefined)
return y
else
return reduce (f) (f (y) (x)) (xs)
}
// derive map from reduce
const map = f => reduce (acc => x => [...acc, f(x)]) ([])
// get max of 2 numbers
const max = x => y => x > y ? x : y
// get max of a list of numbers
const maximum = reduce (max) (-Infinity)
// get each max of a list of a list of numbers
const maximums = map (maximum)
// see the result of your hard work
console.log(maximums ([ [ 1, 3, 2 ], [ 7, 5, 6 ] ]))
// => [ 3, 7 ]
如果你正在努力解决上面的代码,这段代码(下面)是用ES5编写的(更确切地说,是ES6之前的版本)。更熟悉的语法可能会帮助你在你还在削减牙齿的同时。它在ES5中更加冗长,但它的工作(几乎)相同。
// reduce is your new, gold-standard building block
function reduce (f) {
return function (y) {
return function (xs) {
if (xs.length === 0)
return y
else
return reduce (f) (f (y) (xs[0])) (xs.slice(1))
}
}
}
// derive map from reduce
function map (f) {
return reduce (function (acc) {
return function (x) {
return acc.concat([ f(x) ])
}
}) ([])
}
// get max of 2 numbers
function max (x) {
return function (y) {
return x > y ? x : y
}
}
// get max of a list of numbers
var maximum = reduce (max) (-Infinity);
// get each max of a list of a list of numbers
var maximums = map (maximum);
// see the result of your hard work
console.log(maximums ([ [ 1, 3, 2 ], [ 7, 5, 6 ] ]))
// => [ 3, 7 ]
†当然还有函数式编程的其他基础知识,但这肯定是一个好的开始
仍然坚持?
reduce
无疑是上述程序中最复杂的功能。如果你正在努力解决这个问题,我们可以稍微欺骗一下,以缩短我们对该计划的理解。 JavaScript提供了一个内置的Array.prototype.reduce(几乎)工作原理相同。我们可以使用JavaScript编写reduce
并免费获取其余内容!
还有一件事。 JavaScript的reduce需要binary function,但我们程序的其余部分期望curry函数(unary functions的序列)。为了解决这个问题,我们首先会制作一个小uncurry
combinator以使所有内容适合
// convert sequence of unary functions to a binary function
const uncurry = f => (x,y) => f (x) (y)
// we can cheat using JavaScript built-in reduce with uncurry
const reduce = f => y => xs => xs.reduce(uncurry(f), y)
// the rest stays the same !
// ...
// derive map from reduce
const map = f => reduce (acc => x => [...acc, f(x)]) ([])
// get max of 2 numbers
const max = x => y => x > y ? x : y
// get max of a list of numbers
const maximum = reduce (max) (-Infinity)
// get each max of a list of a list of numbers
const maximums = map (maximum)
// see the result of your hard work
console.log(maximums ([ [ 1, 3, 2 ], [ 7, 5, 6 ] ]))
// => [ 3, 7 ]
额外学分1
所以我告诉你reduce
是你的黄金标准构建块。除map
之外,您是否知道您还可以使用reduce
来实现无数其他功能?其中一些包括:filter
,find
,some
,every
,keys
和entries
。
额外学分2
Extra Credit 1 中提到的某些功能应该short-circuit,以便在到达阵列结束之前返回最终答案。哪些可以短路?我们如何重写reduce
以促进这种早退行为呢?
答案 2 :(得分:0)
你试过return max(x);
吗?我想这可能就是你想要的。此外,javascript中还有一个Max(),因此您无需定义它:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max
答案 3 :(得分:0)
您不需要为大多数这些功能推出自己的实现。将Math.max
与Array#map
结合使用,如下所示:
function maximum (array) {
return Math.max.apply(null, array)
}
console.log(
[[1,2,3], [5,6,7]].map(maximum)
) //=> [3, 7]
// if you still want a `maximums` function
function maximums (arrays) {
return arrays.map(maximum)
}
console.log(
maximums([[1,2,3], [5,6,7]]))
) //=> [3, 7]
&#13;
答案 4 :(得分:0)
您可以合并(defn f [a b c]
{:a a :b b :c c})
和map
个功能:
reduce