考虑以下:
val stuff = Map[String,Int]("apple" -> 5,"orange" -> 1,"banana" -> 3,"kiwi" -> 2) val used = 1 val rest = stuff.mapValues{ case quantity => quantity - used }.filterNot{ case (fruit,quantity) => quantity == 0 }
结果是
rest : scala.collection.immutable.Map[String,Int] = Map(apple -> 4,banana -> 2,kiwi -> 1)
虽然我不是Scala的专家,但我知道该语言并不是懒惰的(与Haskell不同),因此mapValues将生成一个中间Map,而后者将作为输入传递给filterNot(如果还有其他操作在链中).
如何避免这种无用的中间数据结构?
注意:我理解这个问题可以推广到其他数据结构.这里我使用的是Map,因为它是我在实际代码中使用的数据结构(尽管有其他数据:))
解决方法
这似乎可以解决问题:
object ChainOpsRS { val stuff = Map[String,"kiwi" -> 2) val used = 1 val rest = stuff.collect { case (fruit,quantity) if quantity > used => (fruit,quantity - used) } def main(args: Array[String]) { printf("stuff=%s%n",stuff.mkString("{",","}")) printf(" rest=%s%n",rest.mkString("{","}")) } }
运行时会产生以下输出:
stuff={apple -> 5,orange -> 1,banana -> 3,kiwi -> 2} rest={apple -> 4,kiwi -> 1}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。