问题描述
val seq = for (i <- (1 to 50) toSeq) yield Seq(s"foo$i",s"bar$i")
,即
List(List("foo1","bar1"),List("foo2","bar2"),...,List("foo50","bar50"))
我也有一个索引元组,比如说
((5,10),(13,17),(25,33),(42,49))
我想要得到的是过滤 seq,只得到索引在第二个元组范围之间的那些,我想在最后一个位置添加一个新的 id。 结果应该是:
List(List("foo5","bar5","0"),List("foo6","bar6","0")...,List("foo10","bar10",List("foo13","bar13","1"),List("foo14","bar14","1")...,List("foo17","bar17",List("foo25","bar25","2"),List("foo26","bar26","2")... List("foo33","bar33",List("foo42","bar42","3"),List("foo43","bar43","3")...,List("foo48","bar48",List("foo49","bar49","3"))
我可以使用过程式编程来实现这一点,但代码味道很难看。这如何以 Scala 风格的函数式方式完成?
解决方法
一般来说,连接类型的操作可以很容易地用 for comprehensions 来表达:
val ranges = Seq((5,10),(13,17),(25,33),(42,49))
for {
i <- (1 to 50).toSeq
((lower,upper),j) <- ranges.zipWithIndex
if i >= lower && i <= upper
} yield List(s"foo$i",s"bar$i",j.toString)
但是请注意,这将需要与两个列表长度的乘积成正比的时间。如果它们足够大,您将需要更优化的解决方案。