(这是this Q&A)的变体
说我有这个:
List( "foo", "bar", "spam" )
我想创建一个Map,其键是String的长度,值是具有该长度的所有字符串的Collection。换句话说,鉴于关于List,我们得到:
Map( 3 -> List(foo, bar), 4 -> List(spam) )
我写的代码是:
list.foldLeft(Map[Long, List[String]]()) {
(m, s) => m(s.length) = s ::
( if ( m.contains(s.length) ) m(s.length)
else Nil )
}
这很有效,但它给Daniel Spiewak提供给原始问题(上面提到的)的优雅答案增添了许多丑陋。
如何改进我的变体的解决方案?
谢谢! 肖恩
答案 0 :(得分:19)
使用Scala 2.8.0:
list.groupBy(_.length)
它不能比那更简单!
答案 1 :(得分:7)
如果你不介意糟糕的表现:
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: _*)
问题是每个不同的长度都会再次读取列表。
现在,关于你的版本的丑陋,也许这会有所帮助:
list.foldLeft(Map[Long, List[String]]()) {
(m, s) => m(s.length) = s :: m.getOrElse(s.length, Nil)
}
更好?它仍然不太好,因为你得到两倍的长度。这个没有这个问题,但它有点丑陋:
list.foldLeft(Map[Long, List[String]]()) {
(m, s) => val length = s.length; m(length) = s :: m.getOrElse(length, Nil)
}