KeyValuePairとListを利用したソート(質問じゃありません) への返答

投稿で使用できる特殊コードの説明。(別タブで開きます。)
本名は入力しないようにしましょう。
投稿した後で削除するときに使うパスワードです。返答があった後は削除できません。
返答する人が目安にします。相手が小学生か社会人かで返答の仕方も変わります。
最初の投稿が質問の場合、質問者が解決時にチェックしてください。(以降も追加書き込み・返信は可能です。)
※「過去ログ」について書くときはその過去ログのURLも書いてください。

以下の返答は逆順(新しい順)に並んでいます。

投稿者 ぽにょ  (社会人) 投稿日時 2009/12/15 11:58:28
ありがとうございました。
あとはがんばってみます。
投稿者 葉月  (社会人) 投稿日時 2009/12/11 04:50:26
魔界の仮面弁士さん、お世話になっています。
アドバイスありがとうございました。

拡張メソッドは、聞いたことしかなかったので早速調べました。
http://msdn.microsoft.com/ja-jp/library/bb383977.aspx

VS2008(.NET Framework3.5)から使える機能だと初めて知りました。
2008を使っていながら、こんな便利な機能があるとは思いもしませんでした。

>>>MSDNから引用
>IEnumerable<(Of <(T>)>) を実装するすべての型は、GroupBy、OrderBy、Average
>などのインスタンス メソッドを持っていると考えられます。

Averageなど他の拡張メソッドを検証し、便利さに驚くばかりです。
Private Sub Button2_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button2.Click
        ' 平均 
        Dim dAverage As Double = Enumerable.Average(dict, Function(x) x.Value)
        Console.WriteLine("Hogeの平均 " & dAverage)
End Sub


魔界の仮面弁士さんのアドバイスがなければ、気づかなかったままだと思います。
有用な情報を提供して頂き感謝しています。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2009/12/10 21:31:04
>> OrderBy 拡張メソッドを使うこともできますね。
> ご提示して頂いたDictionaryのOrderByメソッドに差し替えます。

より正確に言えば、DictionaryのOrderBy拡張メソッドですね。

listHoges = dict.OrderBy(Function(x) x.Value).ToList()
というコードは、
listHoges = Enumerable.OrderBy(dict, Function(x) x.Value).ToList()
の省略表記法です。
投稿者 葉月  (社会人) 投稿日時 2009/12/10 08:19:15
魔界の仮面弁士さん、お世話になっています。
アドバイスありがとうございました。
listHoges = Me.scheduleSort(dict)

提示して頂いた部分は、可読性が悪かったので私も気にしていました。
3点とも差し替えて試しました。
どれも私が提示したコードとは比較にならないぐらいスッキリしており、
毎回、有用な情報を提供していただき感謝しています。

私の元のソースは、
ご提示して頂いたDictionaryのOrderByメソッドに差し替えます。

Linqについても@itで調べて大量のデータを処理するのに、
適しているとわかりました。
http://www.atmarkit.co.jp/fdotnet/csharp30/csharp30_06/csharp30_06_03.html

クエリー式は前に少し触った程度なので実用は先になりそうですが、
Join句など興味があるので少しずつ使っていこうと思います。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2009/12/10 05:51:56
> listHoges = Me.scheduleSort(dict)

OrderBy 拡張メソッドを使うこともできますね。
listHoges = dict.OrderBy(Function(x) x.Value).ToList()


Linq を使う手もあります。
listHoges = (From x In dict Order By x.Value).ToList()


逆順にしたい場合は、Descending を指定すれば OK です。
listHoges = (From x In dict Order By x.Value Descending).ToList()
投稿者 葉月  (社会人) 投稿日時 2009/12/9 08:58:41
質問ではありません。
下記質問の回答の一部になります。
http://rucio.groupsite.jp/commu/ThreadDetail.aspx?ThreadId=9479

ListとKeyValuePairを利用したソートで参考になる可能性があるため、
探しやすくなるよう別スレッドを立てました。


■サンプル
Public Class Form1

    ' Sortで利用 
    Private listHoges As List(Of KeyValuePair(Of StringInteger))
    ' データを格納 
    Private dict As New Dictionary(Of StringInteger)


    Sub New()

        ' この呼び出しは、Windows フォーム デザイナで必要です。 
        InitializeComponent()

        ' InitializeComponent() 呼び出しの後で初期化を追加します。 

        listHoges = New List(Of KeyValuePair(Of StringInteger))
        dict = New Dictionary(Of StringInteger)
    End Sub

    Private Sub Form1_Load(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles MyBase.Load
        dict("Hoge1") = 125
        dict("Hoge2") = 63
        dict("Hoge3") = 255
        dict("Hoge4") = 3
        dict("Hoge5") = 64
        listHoges.AddRange(dict)

        Console.WriteLine(vbCrLf & "■ソート前")

        ' 格納順に表示 
        For Each KeyPair As KeyValuePair(Of StringIntegerIn listHoges
            Console.WriteLine(KeyPair.Key & "■" & KeyPair.Value)
        Next
    End Sub


    Private Sub Button1_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button1.Click
        listHoges = Me.scheduleSort(dict)
        Console.WriteLine(vbCrLf & "■ソート後")

        For Each KeyPair As KeyValuePair(Of StringIntegerIn listHoges
            Console.WriteLine(KeyPair.Key & "■" & KeyPair.Value)
        Next
    End Sub

    ''' <summary> 
    ''' ソートを行う。 
    ''' </summary> 
    ''' <param name="dict">格納されたデータ</param> 
    ''' <returns>ソート後のリスト</returns> 
    Protected Function scheduleSort(ByVal dict As Dictionary(Of StringInteger)) As List(Of KeyValuePair(Of StringInteger))
        Dim lists As New List(Of KeyValuePair(Of StringInteger))(dict)

        '  lists.Sort(Function(keyPair1 As KeyValuePair(Of String, Integer), keyPair2 As KeyValuePair(Of String, Integer)) keyPair2.Value - keyPair1.Value) 
        lists.Sort(Function(keyPair1 As KeyValuePair(Of StringInteger), keyPair2 As KeyValuePair(Of StringInteger)) keyPair1.Value - keyPair2.Value)
        Return lists
    End Function
   
End Class