8

(これは、この Q&Aの変形です)

私がこれを持っているとしましょう:

List( "foo", "bar", "spam" )

キーが文字列の長さであり、値がその長さを持つすべての文字列のコレクションであるマップを作成したいと考えています。言い換えれば、 about 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 が提供したエレガントな回答に多くの醜さを追加します。

私のバリアントのソリューションを改善する方法はありますか?

ありがとう!ショーン

4

2 に答える 2

19

Scala 2.8.0 の場合:

list.groupBy(_.length)

それ以上に簡単なことはありません!

于 2009-07-31T04:21:23.310 に答える
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)
}

より良い?長さを2回取得するため、まだ十分ではありません。これにはこの問題はありませんが、少し醜いです:

list.foldLeft(Map[Long, List[String]]()) {
  (m, s) => val length = s.length; m(length) = s :: m.getOrElse(length, Nil)
}
于 2009-07-30T23:37:15.143 に答える