我从朋友处获得了部分代码,我正在尝试理解它并以其他方式编写代码。 “gotowe”是("2011-12-22",-600.00)
元素的排序列表
val wartosci = gotowe.foldLeft (List(initial_ballance)){
case ((h::t), x) => (x._2 + h)::h::t
case _ => Nil
}.reverse
这是相当不错的,但是如何使用foldLeft? (我已经把所有额外的必要线放了):
val max = wartosci.max
val min = wartosci.min
val wychylenie = if(math.abs(min)>max){math.abs(min)}else{max}
def scale(x: Double) =
(x / wychylenie) * 500
def point(x: Double) =
{val z:Int = (500 - x).toInt
z}
val (points, _) = wartosci.foldLeft(("", 1)){case ((a, i), h) => (a + " " + (i * 4) + "," + point(scale(h)), i + 1)}
当我打印点数时,我有一个值列表,并且不知道为什么不能像值对那样
答案 0 :(得分:5)
这里有几个概念在起作用,我们将依次检查这些概念以确定正在发生的事情:
让我们先来看看foldLeft的定义:
def foldLeft [B](z:B)(f:(B,A)⇒B):B
将二元运算符应用于起始值以及此列表的所有元素,从左到右。
返回在此列表的连续元素之间插入op的结果,从左到右,左边是起始值z:op(... op(z,x1),x2,...,xn)其中x1,...,xn是此列表的元素。
因此,在您的示例中,我们将获取Tuple2 [String,Float](或类似的东西)的列表并将其折叠到值z中,在本例中是一个包含一个元素的List {{1} }。
现在,在这种情况下,我们的initial_balance
是大括号内的代码。它使用模式匹配来组合f
对中的部分函数 - 在这种情况下,(b,a)
是'累积结果',b
是列表中的下一个项目。这是折叠的关键所在 - 它将列表折叠成一个值,使用特定的规则来管理如何一次添加每个元素。
什么是模式匹配/部分功能?模式匹配是一种非常强大的技术,用于从输入数据中调节和提取事物。我们给它一些东西 - 表达式的a
部分 - 告诉它如何在case
之后处理它。这样做的好处是=>
表达式不仅匹配数字或特定字符串,就像java中的switch语句一样,但可以匹配,例如,某个长度的列表或电子邮件地址,或特定的元组。更重要的是,您可以使用它来自动获取匹配的某些部分 - 电子邮件地址的域名,列表的第三个元素等。
我们将看看第一种模式:
case
左侧(case ((h::t), x) => (x._2 + h)::h::t
之前)用于匹配我们正在寻找的值并提取我们关心的特定部分。在这种情况下,我们正在寻找一个元组,其中第一个元素是由头部(=>
)和尾部(h
)组成的列表,第二个元素只是下一个元素列表。 t
是一个提取器模式 - 它匹配对象::(h,t),它通过将h::t
添加到现有List
t来构造h
。
当我们匹配此内容时,我们会按照List
右侧的说明将=>
折叠为累计值。为此,我们采用日期/值元组的右侧(x
),将其添加到列表中的最后一个值(头部),然后将其自身推送到列表的头部。您会注意到这与我们在模式匹配中使用的语法相同 - 使用._2
将元素添加到::
。
在这种情况下,效果是创建正在进行的运行总计。
第二种情况并没有真正做太多 - 这是一个捕获所有情况,但由于这是在折叠中使用它永远不会被调用 - 我们总是会返回看起来像List
的东西
最后,我们扭转了整个事情!因此,我们留下的是每笔交易后的余额清单,从最旧到最年轻。
答案 1 :(得分:1)
这很简单。这只是作业的问题。你有这个:
val (points, _) = wartosci.foldLeft(("", 1)){...}
{...}
内的内容无关紧要。 foldLeft
的第一个参数将确定其结果的类型。由于它是("", 1)
,它将返回(String, Int)
元组。
现在,您将其分配给(points, _)
。像这样的赋值也是模式匹配。就像你写的那样:
var tmp: (String, Int) = _
val tmp: (String, Int) = wartosci.foldLeft(("", 1)){...} match {
case (x, y) => tmp = (x, y)
}
val points = tmp._1
因此,points
只会被分配String
。