Java Scala-意外的MapReduce行为-偶数平方
我正在学习Scala,对一个简单的问题的输出感到困惑 求一个范围内偶数整数的平方和 代码片段1:Java Scala-意外的MapReduce行为-偶数平方,java,scala,mapreduce,scala-collections,Java,Scala,Mapreduce,Scala Collections,我正在学习Scala,对一个简单的问题的输出感到困惑 求一个范围内偶数整数的平方和 代码片段1: val rangeOfNumbers = (1 to 5) val listOfNumbers = rangeOfNumbers.toList val squaresOfEvenNumbers = listOfNumbers .filter(element => element % 2 == 0) .reduce((total, element) => total+
val rangeOfNumbers = (1 to 5)
val listOfNumbers = rangeOfNumbers.toList
val squaresOfEvenNumbers = listOfNumbers
.filter(element => element % 2 == 0)
.reduce((total, element) => total+ (element * element))
println(squaresOfEvenNumbers)
Outputs: 18 -> which is clearly wrong
**EDIT** - Simulation:
I want to square the filtered even numbers - 2,4 and then add them to total variable
1: (total = 0, elem = 2) => 0 + (2 * 2) = 4
2. (total = 4, elem = 4) => 4 + (4 *4 ) = 20
Isn't this the expected behavior?
val rangeOfNumbers = (1 to 5)
val listOfNumbers = rangeOfNumbers.toList
val filteredEvenNumberSquaredList = listOfNumbers
.filter(element => element % 2 == 0)
.map(evenEle => evenEle * evenEle)
.reduce((total, square) => total + square)
println(filteredEvenNumberSquaredList)
Outputs: 20 -> which is correct
代码片段2:
val rangeOfNumbers = (1 to 5)
val listOfNumbers = rangeOfNumbers.toList
val squaresOfEvenNumbers = listOfNumbers
.filter(element => element % 2 == 0)
.reduce((total, element) => total+ (element * element))
println(squaresOfEvenNumbers)
Outputs: 18 -> which is clearly wrong
**EDIT** - Simulation:
I want to square the filtered even numbers - 2,4 and then add them to total variable
1: (total = 0, elem = 2) => 0 + (2 * 2) = 4
2. (total = 4, elem = 4) => 4 + (4 *4 ) = 20
Isn't this the expected behavior?
val rangeOfNumbers = (1 to 5)
val listOfNumbers = rangeOfNumbers.toList
val filteredEvenNumberSquaredList = listOfNumbers
.filter(element => element % 2 == 0)
.map(evenEle => evenEle * evenEle)
.reduce((total, square) => total + square)
println(filteredEvenNumberSquaredList)
Outputs: 20 -> which is correct
你能解释一下第一种方法的错误吗?内部发生了什么?使用
reduce
时,倍增不会应用于第一个元素:
List(2, 4).reduce((sum, el) => sum + el * el)
=> 2 + 4 * 4
=> 18
reduce
(对于非空列表)应满足:
l.reduce(op) == l.tail.foldLeft(l.head)(op)
使用
reduce
时,倍增不会应用于第一个元素:
List(2, 4).reduce((sum, el) => sum + el * el)
=> 2 + 4 * 4
=> 18
reduce
(对于非空列表)应满足:
l.reduce(op) == l.tail.foldLeft(l.head)(op)
第一次调用传递给
.reduce
的lambda时,total
是列表的第一个元素,元素
是第二个元素。你不求前者的平方,只求后者的平方,所以你的结果相差2
您可能想考虑使用<代码> .FoLDLeW而不是<代码>减少< /C> >:
list.foldLeft(0) { case (sum, elem) => sum + elem*elem }
它与.reduce
相同,只是它以您提供的值开始(在本例中为0
),并以相同的方式调用列表中的每个元素,包括第一个元素(它也适用于空列表,而.reduce
会崩溃)
或者,只需list.map(x=>x*x).sum
顺便说一句,您可以对范围本身执行所有过滤/映射等操作-无需首先将其转换为列表:
val squaresOfEvenNumbers = (1 to 5)
.collect { case x if x % 2 == 0 => x*x }
.sum
第一次调用传递给
.reduce
的lambda时,total
是列表的第一个元素,元素
是第二个元素。你不求前者的平方,只求后者的平方,所以你的结果相差2
您可能想考虑使用<代码> .FoLDLeW而不是<代码>减少< /C> >:
list.foldLeft(0) { case (sum, elem) => sum + elem*elem }
它与.reduce
相同,只是它以您提供的值开始(在本例中为0
),并以相同的方式调用列表中的每个元素,包括第一个元素(它也适用于空列表,而.reduce
会崩溃)
或者,只需list.map(x=>x*x).sum
顺便说一句,您可以对范围本身执行所有过滤/映射等操作-无需首先将其转换为列表:
val squaresOfEvenNumbers = (1 to 5)
.collect { case x if x % 2 == 0 => x*x }
.sum
奇怪的是,为什么平方不适用于第一个元素?这是故意的吗?@aces。这就是
reduce
的工作方式。您没有像在foldLeft
/foldRight
中那样提供初始元素,它需要从某个地方开始,以便它抓住集合中的第一个元素并从该元素开始。奇怪的是,为什么平方不应用于第一个元素?这是故意的吗?@aces。这就是reduce
的工作方式。您没有像在foldLeft
/foldRight
中那样提供初始元素,它需要从某个地方开始,这样它才能抓住集合中的第一个元素并从该元素开始。我不确定您所说的“不平方前者,只平方后者,因此,你的结果是2'我想平方过滤后的偶数-2,4,然后将它们添加到总变量1:(total=0,elem=2)=>0+(2*2)=42。(total=4,elem=4)=>4+(4*4)=20这不是预期的行为吗?好吧,它不是(total=0,elem=2)
在第一次调用时,它是(total=2,elem=4)
-这就是问题所在。我明白了,你说的是reduce函数使用第一个元素,即2作为初始总值,然后应用函数。因此,有效地,只进行了一次传递,即:reduce((2,4)=>2+4*4)=18。谢谢你的意见!我不知道你所说的“你不求前者的平方,只求后者的平方,所以你的结果是2”是什么意思。我想把过滤后的偶数-2,4平方,然后把它们加到总变量1中:(total=0,elem=2)=>0+(2*2)=42。(total=4,elem=4)=>4+(4*4)=20这不是预期的行为吗?好吧,它不是(total=0,elem=2)
在第一次调用时,它是(total=2,elem=4)
-这就是问题所在。我明白了,你说的是reduce函数使用第一个元素,即2作为初始总值,然后应用函数。因此,有效地,只进行了一次传递,即:reduce((2,4)=>2+4*4)=18。谢谢你的意见!是什么让您期望第一次呼叫时的总数为0?您没有将0
传递到reduce
任何位置。。。它怎么可能猜出你的意思?我做了一个假设,它会初始化为零。错误的假设它看起来像是什么让你期望第一次调用的总数为0?您没有将0
传递到reduce
任何位置。。。它怎么可能猜出你的意思?我做了一个假设,它会初始化为零。这似乎是个错误的假设