8 scala list map scala-collections
(This is a variant to this Q&A)
Say I have this:
List( "foo", "bar", "spam" )
Run Code Online (Sandbox Code Playgroud)
I want to create a Map for which the key is the length of the String and the value is a Collection of all the Strings that have that length. In other words, given the about List, we'd get:
Map( 3 -> List(foo, bar), 4 -> List(spam) )
Run Code Online (Sandbox Code Playgroud)
The code I've written to do this is:
list.foldLeft(Map[Long, List[String]]()) {
(m, s) => m(s.length) = s ::
( if ( m.contains(s.length) ) m(s.length)
else Nil )
}
Run Code Online (Sandbox Code Playgroud)
This works, but it adds a lot of ugliness to the elegant answer Daniel Spiewak provided to the original question (referenced above).
Any ideas how to improve the solution for my variant?
Thanks! Sean
Wal*_*ang 19
使用Scala 2.8.0:
list.groupBy(_.length)
Run Code Online (Sandbox Code Playgroud)
它不能比这更简单!
如果你不介意糟糕的表现:
val list = List( "foo", "bar", "spam" )
val keyValue = for (length <- list map (_ length) removeDuplicates;
strings = list filter (_.length == length))
yield (length -> strings)
val map = Map(keyValue: _*)
Run Code Online (Sandbox Code Playgroud)
问题是每个不同的长度再次读取列表.
现在,关于你的版本的丑陋,也许这有助于:
list.foldLeft(Map[Long, List[String]]()) {
(m, s) => m(s.length) = s :: m.getOrElse(s.length, Nil)
}
Run Code Online (Sandbox Code Playgroud)
更好?它仍然不太好,因为你得到两倍的长度.这一个没有这个问题,但它有点丑陋:
list.foldLeft(Map[Long, List[String]]()) {
(m, s) => val length = s.length; m(length) = s :: m.getOrElse(length, Nil)
}
Run Code Online (Sandbox Code Playgroud)