2012-04-05 21 views
72

Scalaのリストを2つのフィールドでソートするには、この例ではlastNameとfirstNameでソートしますか?2つのフィールドでScalaのリストを並べ替えるにはどうすればいいですか?

case class Row(var firstName: String, var lastName: String, var city: String) 

var rows = List(new Row("Oscar", "Wilde", "London"), 
       new Row("Otto", "Swift", "Berlin"), 
       new Row("Carl", "Swift", "Paris"), 
       new Row("Hans", "Swift", "Dublin"), 
       new Row("Hugo", "Swift", "Sligo")) 

rows.sortBy(_.lastName) 

私はこの

rows.sortBy(_.lastName + _.firstName) 

のようなものを試してみたが、それは動作しません。だから私は良いと簡単な解決策に興味があります。

答えて

173
rows.sortBy(r => (r.lastName, r.firstName)) 
+4

lastNameで並べ替えを行い、firstNameで自然並べ替えをしたい場合はどうすればいいですか? –

+9

@SachinK: 'Row'クラス用に独自の' Ordering'を作成し、 'rows.sorted(customOrdering)'のような 'sorted'メソッドでそれを使用する必要があります。 'Tuple2'にカスタム' Ordering'を使うこともできます: 'rows.sortBy(r =>(r.lastName、r.firstName))(Ordering.Tuple2(Ordering.String.reverse、Ordering.String))' 。 – senia

+4

@SachinK: 'customOrdering'を手動でOrdering [Row]'として実装するか、次のように 'Ordering.by'を使って実装することができます:' val customOrdering = 'Ordering.by((r:Row)=>(r.lastName、r .firstName))(Ordering.Tuple2(Ordering.String.reverse、Ordering.String)) ' – senia

9
rows.sortBy (row => row.lastName + row.firstName) 

あなたが最初のlastNameの、その後のfirstNameでソートしたい場合は、あなたの質問のようにマージされた名前でソートしたい、または

rows.sortBy (row => (row.lastName, row.firstName)) 

場合。より長い名前に関連しています(ワイルド、ワイルダー、ワイルダーマン)。

あなたは2つの下線付き

rows.sortBy(_.lastName + _.firstName) 

を記述する場合、メソッドは、2つのパラメータを期待:あなたは安定ソートアルゴリズムを使用する場合、一般的に

<console>:14: error: wrong number of parameters; expected = 1 
     rows.sortBy (_.lastName + _.firstName) 
          ^
+1

この順序は、おそらくfirstname、次にlastnameによるソートと同じではありません。 – Marcin

+1

特に、姓が異なる場合、 –

+0

@Marcin:lastName、firstNameの順になります。はい、あなたが正しい。 –

5

、あなただけの並べ替えつのキーによってでき、それから次の

rows.sortBy(_.firstName).sortBy(_.lastName) 

最終結果は、姓でソートされます。次に、姓でソートされます。

+0

scala 'sortBy'は安定したソートを使用していますか?さもなければ、この答えは無意味です。 –

+1

@ om-nom-nom:http://www.scala-lang.org/api/current/scala/util/Sorting$.html quickSortは値型に対してのみ定義されています。 – Marcin

+1

'rows'は不変なリストであり、' sortBy'は(変更可能なクラスであっても)それが動作するものを変更するのではなく、新しい値を返します。つまり、2番目の式は、ソートされていない元のリストを並べ替えるだけです。 –

-4

おそらくこれは、唯一のタプルのリストのために動作しますが、

scala> var zz = List((1, 0.1), (2, 0.5), (3, 0.6), (4, 0.3), (5, 0.1)) 
zz: List[(Int, Double)] = List((1,0.1), (2,0.5), (3,0.6), (4,0.3), (5,0.1)) 

scala> zz.sortBy(x => (-x._2, x._1)) 
res54: List[(Int, Double)] = List((3,0.6), (2,0.5), (4,0.3), (1,0.1), (5,0.1)) 

は、それを表現するための簡単な方法で作業してあるように思われます。

+0

しかし、文字列には機能しません。これは、OPがソートしているものです。 –

+0

この質問には、タプルのリストに限定されていないいくつかの回答があります。だからそれを掲示する理由は何ですか? – honk

+0

@honk:タプルのリストに対して、従来のソリューションは実際には機能しません(AFAICT)。私がScalaの初心者でなかった場合、おそらく私はそのような従来のソリューションをそのように変える方法を理解するだろうが、今日はそうではない。私の答えは、私がやっているのと同じことをScalaの初心者が手助けするかもしれないと思った。 – spreinhardt

関連する問題