我对Scala相当陌生,但我想知道解决这个问题的首选方式是什么。 假设我有一个项目清单,我想知道检查项目的总量。 我可以这样做:
val total = items.filter(_.itemType == CHECK).map(._amount).sum这会给我我需要的东西,所有检查的总和都在一个不可变的变量中。 但它看起来像3次迭代。 一旦过滤检查,再次映射金额,然后总和。 另一种方法是做类似的事情:
var total = new BigDecimal(0) for ( item <- items if item.itemType == CHECK ) total += item.amount这给了我相同的结果,但1迭代和一个可变的变量,这似乎也很好。 但是如果我想要提取更多信息,请说明检查的总数,这将需要更多的计数器或可变变量,但我不必再次遍历列表。 似乎不像实现我所需要的“功能”方式。
var numOfChecks = 0 var total = new BigDecimal(0) items.foreach { item => if (item.itemType == CHECK) { numOfChecks += 1 total += item.amount } }所以,如果你发现自己需要一堆计数器或列表中的总数,那么最好保留可变变量或不要担心它会按照以下方式进行操作:
val checks = items.filter(_.itemType == CHECK) val total = checks.map(_.amount).sum return (checks.size, total)这似乎更容易阅读,只使用vals
I'm pretty new to Scala but I like to know what is the preferred way of solving this problem. Say I have a list of items and I want to know the total amount of the items that are checks. I could do something like so:
val total = items.filter(_.itemType == CHECK).map(._amount).sumThat would give me what I need, the sum of all checks in a immutable variable. But it does it with what seems like 3 iterations. Once to filter the checks, again to map the amounts and then the sum. Another way would be to do something like:
var total = new BigDecimal(0) for ( item <- items if item.itemType == CHECK ) total += item.amountThis gives me the same result but with 1 iteration and a mutable variable which seems fine too. But if I wanted to to extract more information, say the total number of checks, that would require more counters or mutable variables but I wouldn't have to iterate over the list again. Doesn't seem like the "functional" way of achieving what I need.
var numOfChecks = 0 var total = new BigDecimal(0) items.foreach { item => if (item.itemType == CHECK) { numOfChecks += 1 total += item.amount } }So if you find yourself needing a bunch of counters or totals on a list is it preferred to keep mutable variables or not worry about it do something along the lines of:
val checks = items.filter(_.itemType == CHECK) val total = checks.map(_.amount).sum return (checks.size, total)which seems easier to read and only uses vals
最满意答案
你可以使用foldLeft :
(0 /: items) ((total, item) => if(item.itemType == CHECK) total + item.amount else total )以下代码将返回一个元组(检查次数 - >金额总和):
((0, 0) /: items) ((total, item) => if(item.itemType == CHECK) (total._1 + 1, total._2 + item.amount) else total )You may use foldLeft for that:
(0 /: items) ((total, item) => if(item.itemType == CHECK) total + item.amount else total )The following code will return a tuple (number of checks -> sum of amounts):
((0, 0) /: items) ((total, item) => if(item.itemType == CHECK) (total._1 + 1, total._2 + item.amount) else total )更多推荐
发布评论