2013-08-07T22:55:54の更新内容

programming/netfx/collections/2_generic_3_sortedlist_sorteddictionary/index.wiki.txt

current previous
11,478 11,9
 
#googleadunit(banner)
#googleadunit(banner)
 

        

        
 
*SortedListとSortedDictionary [#SortedListSortedDictionary]
*SortedListとSortedDictionary [#SortedListSortedDictionary]
~
&msdn(netfx,type,System.Collections.Generic.SortedList`2){System.Collections.Generic.SortedListクラス};と&msdn(netfx,type,System.Collections.Generic.SortedDictionary`2){System.Collections.Generic.SortedDictionaryクラス};は非常によく似たコレクションクラスです。 どちらも[[Dictionaryクラス>programming/netfx/collections/2_generic_2_dictionary#Dictionary]]と同じようにキーと値の対(ペア)で要素を格納します。 キーを指定することにより、そのキーに対応する要素の値を取得することができます。
&msdn(netfx,type,System.Collections.Generic.SortedList`2){System.Collections.Generic.SortedListクラス};と&msdn(netfx,type,System.Collections.Generic.SortedDictionary`2){System.Collections.Generic.SortedDictionaryクラス};は非常によく似たコレクションクラスで、どちらも[[Dictionaryクラス>programming/netfx/collections/2_generic_2_dictionary#Dictionary]]のようにキーと値のペアで要素を格納し、格納した要素は[[System.Collections.SortedListクラス>programming/netfx/collections/1_nongeneric_3_sortedlist#SortedList]]のようにキーに基づいて並べ替えられます。
 

        

        
~
SortedListクラス・SortedDictionaryクラスでは、要素が設定(追加)される時点で''キーに基づいて自動的に要素の並べ替え(ソート)''が行われます。 これはDictionaryには無い機能です。 Sortedの名前が示す通り、格納される要素は''常にソートされた状態''になります。
#tabpage(codelang=cs)
+

          
+
これらの特徴はSortedListとSortedDictionaryに共通するものですが、SortedListとSortedDictionaryの相違点の1つに[[インデックスを指定したアクセスができるかどうか>#indexed_access]]があります。
+

          
+
SortedListは名前が示すとおり[[List>programming/netfx/collections/2_generic_1_list]]と似た特徴を持ち、インデックスを指定してキーや値を取得したり、逆にキーや値からインデックスを検索したりすることができます。 一方、SortedDictionaryはDictionaryと同様にインデックスを指定したアクセスはできません。 このような特徴と関連して、[[要素の挿入・削除操作の速度やメモリ使用量などのパフォーマンス面>#performance]]にも違いが現れます。
+

          
+
SortedListに格納される要素に割り振られるインデックスは、あくまで''各要素を並べ替えた時の順序''となります。 Listのように''要素を追加した順にインデックスが割り振られるわけではありません''。 キー・値のペアで要素を格納し、かつ要素を追加した順にインデックスを割り振りたい場合は&msdn(netfx,type,System.Collections.Specialized.OrderedDictionary){OrderedDictionaryクラス};を使います。
+

          
+
*基本操作
+
**インスタンスの作成・要素の取得・設定・列挙
+
インスタンスの作成、要素の取得と設定、要素の列挙などの操作は[[Dictionaryクラス>programming/netfx/collections/2_generic_2_dictionary#Dictionary]]を使う場合と変わりありません。 foreach文で列挙を行う際に''ソートされた状態で''列挙される点のみが異なります。
+

          
+
#tabpage(codelang=cs,SortedList/C#)
+
#code{{
+
using System;
+
using System.Collections.Generic;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    // インスタンスの作成
+
    SortedList<string, int> list = new SortedList<string, int>();
+

          
+
    // 要素の設定
+
    list["Dave"]    = 1;
+
    list["Alice"]   = 2;
+
    list["Bob"]     = 3;
+
    list["Eve"]     = 4;
+
    list["Charlie"] = 5;
+

          
+
    // 格納されている要素の列挙
+
    foreach (KeyValuePair<string, int> pair in list)
+
    {
+
      Console.WriteLine("{0,-8} => {1}", pair.Key, pair.Value);
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=cs,SortedDictionary/C#)
+
#code{{
+
using System;
+
using System.Collections.Generic;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    // インスタンスの作成
+
    SortedDictionary<string, int> dict = new SortedDictionary<string, int>();
+

          
+
    // 要素の設定
+
    dict["Dave"]    = 1;
+
    dict["Alice"]   = 2;
+
    dict["Bob"]     = 3;
+
    dict["Eve"]     = 4;
+
    dict["Charlie"] = 5;
+

          
+
    // 格納されている要素の列挙
+
    foreach (KeyValuePair<string, int> pair in dict)
+
    {
+
      Console.WriteLine("{0,-8} => {1}", pair.Key, pair.Value);
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb,SortedList/VB)
+
#code{{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' インスタンスの作成
+
    Dim list As New SortedList(Of String, Integer)()
+

          
+
    ' 要素の設定
+
    list("Dave")    = 1
+
    list("Alice")   = 2
+
    list("Bob")     = 3
+
    list("Eve")     = 4
+
    list("Charlie") = 5
+

          
+
    ' 格納されている要素の列挙
+
    For Each pair As KeyValuePair(Of String, Integer) In list
+
      Console.WriteLine("{0,-8} => {1}", pair.Key, pair.Value)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage(codelang=vb,SortedDictionary/VB)
+
#code{{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' インスタンスの作成
+
    Dim dict As New SortedDictionary(Of String, Integer)()
+

          
+
    ' 要素の設定
+
    dict("Dave")    = 1
+
    dict("Alice")   = 2
+
    dict("Bob")     = 3
+
    dict("Eve")     = 4
+
    dict("Charlie") = 5
+

          
+
    ' 格納されている要素の列挙
+
    For Each pair As KeyValuePair(Of String, Integer) In dict
+
      Console.WriteLine("{0,-8} => {1}", pair.Key, pair.Value)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
Alice    => 2
+
Bob      => 3
+
Charlie  => 5
+
Dave     => 1
+
Eve      => 4
+
}}
+

          
+
Keysプロパティを列挙した場合も同様に、キーがソートされた状態で列挙されます。 Valuesプロパティを列挙した場合は、ソートされたキーと同じ順序でキーに対応する値が列挙されます(値単独でソートされた順序にはなりません)。
+

          
+
#tabpage(codelang=cs,SortedList/C#)
+
#code{{
+
using System;
+
using System.Collections.Generic;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    // インスタンスの作成
+
    SortedList<string, int> list = new SortedList<string, int>();
+

          
+
    // 要素の設定
+
    list["Dave"]    = 1;
+
    list["Alice"]   = 2;
+
    list["Bob"]     = 3;
+
    list["Eve"]     = 4;
+
    list["Charlie"] = 5;
+

          
+
    // 格納されているキーの列挙
+
    foreach (string key in list.Keys)
+
    {
+
      Console.WriteLine(key);
+
    }
+

          
+
     // 格納されている値の列挙
+
    foreach (int val in list.Values)
+
    {
+
      Console.WriteLine(val);
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=cs,SortedDictionary/C#)
+
#code{{
+
using System;
+
using System.Collections.Generic;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    // インスタンスの作成
+
    SortedDictionary<string, int> dict = new SortedDictionary<string, int>();
+

          
+
    // 要素の設定
+
    dict["Dave"]    = 1;
+
    dict["Alice"]   = 2;
+
    dict["Bob"]     = 3;
+
    dict["Eve"]     = 4;
+
    dict["Charlie"] = 5;
+

          
+
    // 格納されているキーの列挙
+
    foreach (string key in dict.Keys)
+
    {
+
      Console.WriteLine(key);
+
    }
+

          
+
     // 格納されている値の列挙
+
    foreach (int val in dict.Values)
+
    {
+
      Console.WriteLine(val);
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb,SortedList/VB)
+
#code{{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' インスタンスの作成
+
    Dim list As New SortedList(Of String, Integer)()
+

          
+
    ' 要素の設定
+
    list("Dave")    = 1
+
    list("Alice")   = 2
+
    list("Bob")     = 3
+
    list("Eve")     = 4
+
    list("Charlie") = 5
+

          
+
    ' 格納されているキーの列挙
+
    For Each key As String In list.Keys
+
      Console.WriteLine(key)
+
    Next
+

          
+
    ' 格納されている値の列挙
+
    For Each value As Integer In list.Values
+
      Console.WriteLine(value)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage(codelang=vb,SortedDictionary/VB)
+
#code{{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' インスタンスの作成
+
    Dim dict As New SortedDictionary(Of String, Integer)()
+

          
+
    ' 要素の設定
+
    dict("Dave")    = 1
+
    dict("Alice")   = 2
+
    dict("Bob")     = 3
+
    dict("Eve")     = 4
+
    dict("Charlie") = 5
+

          
+
    ' 格納されているキーの列挙
+
    For Each key As String In dict.Keys
+
      Console.WriteLine(key)
+
    Next
+

          
+
    ' 格納されている値の列挙
+
    For Each value As Integer In dict.Values
+
      Console.WriteLine(value)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
Alice
+
Bob
+
Charlie
+
Dave
+
Eve
+
2
+
3
+
5
+
1
+
4
+
}}
+

          
+

          
+
**コレクション初期化子
+
Dictionaryの場合と同様、SortedList・SortedDictionaryでもコレクション初期化子を使ってインスタンスの作成と要素の追加を同時に行うことができます。 コレクション初期化子はC# 3.0(Visual C# 2008)以降、VB 10(Visual Basic 2010)以降でサポートされます。
+

          
+
#tabpage(codelang=cs,SortedList/C#)
+
#code{{
+
using System;
+
using System.Collections.Generic;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    // コレクション初期化子を使ってインスタンスの作成と要素の追加を行う
+
    SortedList<string, int> list = new SortedList<string, int>() {
+
      {"Dave",    1},
+
      {"Alice",   2},
+
      {"Bob",     3},
+
      {"Eve",     4},
+
      {"Charlie", 5},
+
    };
+

          
+
    Console.WriteLine("Count = {0}", dict.Count);
+
    Console.WriteLine("Eve => {0}", dict["Eve"]);
+
  }
+
}
+
}}
+
#tabpage(codelang=cs,SortedDictionary/C#)
+
#code{{
+
using System;
+
using System.Collections.Generic;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    // コレクション初期化子を使ってインスタンスの作成と要素の追加を行う
+
    SortedDictionary<string, int> dict = new SortedDictionary<string, int>() {
+
      {"Dave",    1},
+
      {"Alice",   2},
+
      {"Bob",     3},
+
      {"Eve",     4},
+
      {"Charlie", 5},
+
    };
+

          
+
    Console.WriteLine("Count = {0}", dict.Count);
+
    Console.WriteLine("Eve => {0}", dict["Eve"]);
+
  }
+
}
+
}}
+
#tabpage(codelang=vb,SortedList/VB)
+
#code{{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' コレクション初期化子を使ってインスタンスの作成と要素の追加を行う
+
    Dim list As New SortedList(Of String, Integer)() From {
+
      {"Dave",    1},
+
      {"Alice",   2},
+
      {"Bob",     3},
+
      {"Eve",     4},
+
      {"Charlie", 5}
+
    }
+

          
+
    Console.WriteLine("Count = {0}", list.Count)
+
    Console.WriteLine("Eve => {0}", list("Eve"))
+
  End Sub
+
End Class
+
}}
+
#tabpage(codelang=vb,SortedDictionary/VB)
+
#code{{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' コレクション初期化子を使ってインスタンスの作成と要素の追加を行う
+
    Dim dict As New SortedDictionary(Of String, Integer)() From {
+
      {"Dave",    1},
+
      {"Alice",   2},
+
      {"Bob",     3},
+
      {"Eve",     4},
+
      {"Charlie", 5}
+
    }
+

          
+
    Console.WriteLine("Count = {0}", dict.Count)
+
    Console.WriteLine("Eve => {0}", dict("Eve"))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
Count = 5
+
Eve => 4
+
}}
+

          
+

          
+
**存在しないキーを参照した場合・既にキーが存在する場合
+
存在しないキーを参照した場合の動作はDictionaryと同様で、例外&msdn(netfx,type,System.Collections.Generic.KeyNotFoundException){KeyNotFoundException};がスローされます。
+

          
+
#tabpage(codelang=cs,SortedList/C#)
+
#code{{
+
using System;
+
using System.Collections.Generic;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    SortedList<string, int> list = new SortedList<string, int>();
+

          
+
    list["foo"] = 16;
+
    list["bar"] = 72;
+

          
+
    // 存在するキーに対応する値を取得
+
    Console.WriteLine("foo = {0}", list["foo"]);
+
    Console.WriteLine("bar = {0}", list["bar"]);
+

          
+
    // 存在しないキー"hoge"に対応する値を取得
+
    Console.WriteLine("hoge = {0}", list["hoge"]);
+
  }
+
}
+
}}
+
#tabpage(codelang=cs,SortedDictionary/C#)
+
#code{{
+
using System;
+
using System.Collections.Generic;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    SortedDictionary<string, int> dict = new SortedDictionary<string, int>();
+

          
+
    dict["foo"] = 16;
+
    dict["bar"] = 72;
+

          
+
    // 存在するキーに対応する値を取得
+
    Console.WriteLine("foo = {0}", dict["foo"]);
+
    Console.WriteLine("bar = {0}", dict["bar"]);
+

          
+
    // 存在しないキー"hoge"に対応する値を取得
+
    Console.WriteLine("hoge = {0}", dict["hoge"]);
+
  }
+
}
+
}}
+
#tabpage(codelang=vb,SortedList/VB)
+
#code{{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim list As New SortedList(Of String, Integer)()
+

          
+
    list("foo") = 16
+
    list("bar") = 72
+

          
+
    ' 存在するキーに対応する値を取得
+
    Console.WriteLine("foo = {0}", list("foo"))
+
    Console.WriteLine("bar = {0}", list("bar"))
+

          
+
    ' 存在しないキー"hoge"に対応する値を取得
+
    Console.WriteLine("hoge = {0}", list("hoge"))
+
  End Sub
+
End Class
+
}}
+
#tabpage(codelang=vb,SortedDictionary/VB)
+
#code{{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim dict As New SortedDictionary(Of String, Integer)()
+

          
+
    dict("foo") = 16
+
    dict("bar") = 72
+

          
+
    ' 存在するキーに対応する値を取得
+
    Console.WriteLine("foo = {0}", dict("foo"))
+
    Console.WriteLine("bar = {0}", dict("bar"))
+

          
+
    ' 存在しないキー"hoge"に対応する値を取得
+
    Console.WriteLine("hoge = {0}", dict("hoge"))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
foo = 16
+
bar = 72
+

          
+
ハンドルされていない例外: System.Collections.Generic.KeyNotFoundException: 指定されたキーはディレクトリ内に存在しませんでした。
+
   場所 System.Collections.Generic.SortedDictionary`2.get_Item(TKey key)
+
   場所 Sample.Main()
+
}}
+

          
+
キーを指定した上書き・追加の動作もDictionaryと同様です。 インデクサで既に存在するキーを指定した場合は''値が上書き''され、Addメソッドで既に存在するキーを指定した場合は''例外&msdn(netfx,type,System.ArgumentException){ArgumentException};がスロー''されます。
+

          
+
#tabpage(codelang=cs,SortedList/C#)
 
#code{{
#code{{
 
using System;
using System;
 
using System.Collections.Generic;
using System.Collections.Generic;
493,50 24,37
 
  {
  {
 
    SortedList<string, int> list = new SortedList<string, int>();
    SortedList<string, int> list = new SortedList<string, int>();
 

        

        
~
    list["foo"] = 16;
    list.Add("Dave", 1);
-
    list.Add("Alice", 2);
-
    list.Add("Bob", 3);
-
    list.Add("Eve", 4);
-
    list.Add("Charlie", 5);
 

        

        
~
    Console.WriteLine("foo = {0}", list["foo"]);
    Console.WriteLine("[SortedList]");
 

        

        
~
    // 既に存在するキーを指定して値を上書き
    foreach (KeyValuePair<string, int> pair in list)
~
    list["foo"] = 72;
    {
~

          
      Console.WriteLine("{0} => {1}", pair.Key, pair.Value);
~
    Console.WriteLine("foo = {0}", list["foo"]);
    }
+

          
+
    // 既に存在するキーを指定して値を追加
+
    list.Add("foo", 42);
+

          
+
    Console.WriteLine("foo = {0}", list["foo"]);
+
  }
+
}
+
}}
+
#tabpage(codelang=cs,SortedDictionary/C#)
+
#code{{
+
using System;
+
using System.Collections.Generic;
 

        

        
+
class Sample
+
{
+
  static void Main()
+
  {
 
    SortedDictionary<string, int> dict = new SortedDictionary<string, int>();
    SortedDictionary<string, int> dict = new SortedDictionary<string, int>();
 

        

        
~
    dict["foo"] = 16;
    dict.Add("Dave", 1);
-
    dict.Add("Alice", 2);
-
    dict.Add("Bob", 3);
-
    dict.Add("Eve", 4);
-
    dict.Add("Charlie", 5);
 

        

        
~
    Console.WriteLine("foo = {0}", dict["foo"]);
    Console.WriteLine("[SortedDictionary]");
 

        

        
~
    // 既に存在するキーを指定して値を上書き
    foreach (KeyValuePair<string, int> pair in dict)
~
    dict["foo"] = 72;
    {
~

          
      Console.WriteLine("{0} => {1}", pair.Key, pair.Value);
~
    Console.WriteLine("foo = {0}", dict["foo"]);
    }
+

          
+
    // 既に存在するキーを指定して値を追加
+
    dict.Add("foo", 42);
+

          
+
    Console.WriteLine("foo = {0}", dict["foo"]);
 
  }
  }
 
}
}
 
}}
}}
~
#tabpage(codelang=vb,SortedList/VB)
#tabpage(codelang=vb)
 
#code{{
#code{{
 
Imports System
Imports System
 
Imports System.Collections.Generic
Imports System.Collections.Generic
545,63 63,53
 
  Shared Sub Main()
  Shared Sub Main()
 
    Dim list As New SortedList(Of String, Integer)()
    Dim list As New SortedList(Of String, Integer)()
 

        

        
~
    list("foo") = 16
    list.Add("Dave", 1)
-
    list.Add("Alice", 2)
-
    list.Add("Bob", 3)
-
    list.Add("Eve", 4)
-
    list.Add("Charlie", 5)
 

        

        
~
    Console.WriteLine("foo = {0}", list("foo"))
    Console.WriteLine("[SortedList]")
 

        

        
~
    ' 既に存在するキーを指定して値を上書き
    For Each pair As KeyValuePair(Of String, Integer) In list
~
    list("foo") = 72
      Console.WriteLine("{0} => {1}", pair.Key, pair.Value)
~

          
    Next
+
    Console.WriteLine("foo = {0}", list("foo"))
+

          
+
    ' 既に存在するキーを指定して値を追加
+
    list.Add("foo", 42)
+

          
+
    Console.WriteLine("foo = {0}", list("foo"))
+
  End Sub
+
End Class
+
}}
+
#tabpage(codelang=vb,SortedDictionary/VB)
+
#code{{
+
Imports System
+
Imports System.Collections.Generic
 

        

        
+
Class Sample
+
  Shared Sub Main()
 
    Dim dict As New SortedDictionary(Of String, Integer)()
    Dim dict As New SortedDictionary(Of String, Integer)()
 

        

        
~
    dict("foo") = 16
    dict.Add("Dave", 1)
-
    dict.Add("Alice", 2)
-
    dict.Add("Bob", 3)
-
    dict.Add("Eve", 4)
-
    dict.Add("Charlie", 5)
 

        

        
~
    Console.WriteLine("foo = {0}", dict("foo"))
    Console.WriteLine("[SortedDictionary]")
 

        

        
~
    ' 既に存在するキーを指定して値を上書き
    For Each pair As KeyValuePair(Of String, Integer) In dict
~
    dict("foo") = 72
      Console.WriteLine("{0} => {1}", pair.Key, pair.Value)
~

          
    Next
+
    Console.WriteLine("foo = {0}", dict("foo"))
+

          
+
    ' 既に存在するキーを指定して値を追加
+
    dict.Add("foo", 42)
+

          
+
    Console.WriteLine("foo = {0}", dict("foo"))
 
  End Sub
  End Sub
 
End Class
End Class
 
}}
}}
 
#tabpage-end
#tabpage-end
 

        

        
 
#prompt(実行結果){{
#prompt(実行結果){{
~
foo = 16
[SortedList]
~
foo = 72
Alice => 2
~

          
Bob => 3
~
ハンドルされていない例外: System.ArgumentException: 同一のキーを含む項目が既に追加されています。
Charlie => 5
~
   場所 System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
Dave => 1
~
   場所 System.Collections.Generic.TreeSet`1.AddIfNotPresent(T item)
Eve => 4
~
   場所 System.Collections.Generic.SortedDictionary`2.Add(TKey key, TValue value)
[SortedDictionary]
~
   場所 Sample.Main()
Alice => 2
-
Bob => 3
-
Charlie => 5
-
Dave => 1
-
Eve => 4
 
}}
}}
 

        

        
~

          
**基本操作
~
**要素の検索・削除・存在チェック
SortedListクラスとSortedDictionaryクラスでは、ContainsKeyメソッドやTryGetValueメソッドなど、概ね[[Dictionaryクラス>programming/netfx/collections/2_generic_2_dictionary#Dictionary]]と同様の操作が行えるようになっています。
+
[[Dictionaryクラス>programming/netfx/collections/2_generic_2_dictionary#Dictionary]]と同様、ContainsKeyメソッドやTryGetValueメソッドなどを使うことができます。
 

        

        
 
#tabpage(codelang=cs,SortedList/C#)
#tabpage(codelang=cs,SortedList/C#)
 
#code{{
#code{{
781,258 289,46
 
    ' キー"bar"の要素を削除
    ' キー"bar"の要素を削除
 
    dict.Remove("bar")
    dict.Remove("bar")
 

        

        
~
    For Each pair As KeyValuePair(Of String, Integer) In dict
    For Each pair As KeyValuePair(Of String, Integer) In dict
~
      Console.WriteLine("{0} => {1}", pair.Key, pair.Value)
      Console.WriteLine("{0} => {1}", pair.Key, pair.Value)
+
    Next
+

          
+
    ' キー"baz"に該当する値を取得
+
    Dim valueOfBaz As Integer
+

          
+
    If dict.TryGetValue("baz", valueOfBaz) Then
+
      Console.WriteLine("value of 'baz': {0}", valueOfBaz)
+
    Else
+
      Console.WriteLine("key not found")
+
    End If
+

          
+
    ' キー"hoge"に該当する値を取得
+
    Dim valueOfHoge As Integer
+

          
+
    If dict.TryGetValue("hoge", valueOfHoge) Then
+
      Console.WriteLine("value of 'hoge': {0}", valueOfHoge)
+
    Else
+
      Console.WriteLine("key not found")
+
    End If
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
True
+
False
+
baz => 42
+
foo => 16
+
value of 'baz': 42
+
key not found
+
}}
+

          
+
**インデックスを指定した操作 [#indexed_access]
+
SortedListクラスでは、インデックスを指定してキー・値へアクセスすることができます。 &msdn(netfx,member,System.Collections.Generic.SortedList`2.Keys){Keysプロパティ};および&msdn(netfx,member,System.Collections.Generic.SortedList`2.Values){Valuesプロパティ};では、インデックスを指定することで個々の要素のキーと値を取得できます。
+

          
+
#tabpage(codelang=cs)
+
#code{{
+
using System;
+
using System.Collections.Generic;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    SortedList<string, int> list = new SortedList<string, int>();
+

          
+
    list["Dave"]    = 1;
+
    list["Alice"]   = 2;
+
    list["Bob"]     = 3;
+
    list["Eve"]     = 4;
+
    list["Charlie"] = 5;
+

          
+
    for (int i = 0; i < list.Count; i++)
+
    {
+
      // インデックスを指定してキーと値を取得
+
      Console.WriteLine("[{0}] {1,-8} => {2}", i, list.Keys[i], list.Values[i]);
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim list As New SortedList(Of String, Integer)()
+

          
+
    list("Dave")    = 1
+
    list("Alice")   = 2
+
    list("Bob")     = 3
+
    list("Eve")     = 4
+
    list("Charlie") = 5
+

          
+
    For i As Integer = 0 To list.Count - 1
+
      ' インデックスを指定してキーと値を取得
+
      Console.WriteLine("[{0}] {1,-8} => {2}", i, list.Keys(i), list.Values(i))
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
[0] Alice    => 2
+
[1] Bob      => 3
+
[2] Charlie  => 5
+
[3] Dave     => 1
+
[4] Eve      => 4
+
}}
+

          
+
なお、Keysプロパティ・Valuesプロパティを使ってインデックスを指定した値・キーの設定を行うことはできません。
+

          
+
SortedListでは、ソートされた順に従って各要素にインデックスが割り振られます(要素が追加された順ではありません)。 インデックス0の要素は、並べ替えた際に最初に位置する要素となります。 要素の追加や削除が行われる度に並べ替えられるため、要素に割り振られていたインデックスが変わることもあります。
+

          
+
#tabpage(codelang=cs)
+
#code{{
+
using System;
+
using System.Collections.Generic;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    SortedList<string, int> list = new SortedList<string, int>();
+

          
+
    list["Dave"]  = 1;
+
    list["Bob"]   = 3;
+

          
+
    // インデックス0のキーと値を取得
+
    Console.WriteLine("{0,-8} => {1}", list.Keys[0], list.Values[0]);
+

          
+
    // 要素を削除
+
    list.Remove("Bob");
+

          
+
    // インデックス0のキーと値を取得
+
    Console.WriteLine("{0,-8} => {1}", list.Keys[0], list.Values[0]);
+

          
+
    // 要素を追加
+
    list.Add("Alice", 2);
+

          
+
    // インデックス0のキーと値を取得
+
    Console.WriteLine("{0,-8} => {1}", list.Keys[0], list.Values[0]);
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim list As New SortedList(Of String, Integer)()
+

          
+
    list("Dave")  = 1
+
    list("Bob")   = 3
+

          
+
    ' インデックス0のキーと値を取得
+
    Console.WriteLine("{0,-8} => {1}", list.Keys(0), list.Values(0))
+

          
+
    ' 要素を削除
+
    list.Remove("Bob")
+

          
+
    ' インデックス0のキーと値を取得
+
    Console.WriteLine("{0,-8} => {1}", list.Keys(0), list.Values(0))
+

          
+
    ' 要素を追加
+
    list.Add("Alice", 2)
+

          
+
    ' インデックス0のキーと値を取得
+
    Console.WriteLine("{0,-8} => {1}", list.Keys(0), list.Values(0))
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
Bob      => 3
+
Dave     => 1
+
Alice    => 2
+
}}
+

          
+
キーや値からインデックスを取得したい場合は、&msdn(netfx,member,System.Collections.Generic.SortedList`2.IndexOfKey){IndexOfKeyメソッド};および&msdn(netfx,member,System.Collections.Generic.SortedList`2.IndexOfValue){IndexOfValueメソッド};を使うことでキー・値のインデックスを取得することができます。 SortedListに該当するキー・値が存在しない場合は-1が返されます。
+

          
+
#tabpage(codelang=cs)
+
#code{{
+
using System;
+
using System.Collections.Generic;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    SortedList<string, int> list = new SortedList<string, int>();
+

          
+
    list["Dave"]    = 1;
+
    list["Alice"]   = 2;
+
    list["Bob"]     = 3;
+
    list["Eve"]     = 4;
+
    list["Charlie"] = 5;
+

          
+
    // インデックス・キー・値の一覧を表示
+
    for (int i = 0; i < list.Count; i++)
+
    {
+
      Console.WriteLine("[{0}] {1,-8} => {2}", i, list.Keys[i], list.Values[i]);
+
    }
+

          
+
    Console.WriteLine();
+

          
+
    // キー"Charlie"を持つ要素のインデックスを取得
+
    Console.WriteLine("IndexOfKey 'Charlie': {0}", list.IndexOfKey("Charlie"));
+

          
+
    // 値2を持つ要素のインデックスを取得
+
    Console.WriteLine("IndexOfValue 2: {0}", list.IndexOfValue(2));
+

          
+
    // 値42を持つ要素のインデックスを取得
+
    Console.WriteLine("IndexOfValue 42: {0}", list.IndexOfValue(42));
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim list As New SortedList(Of String, Integer)()
+

          
+
    list("Dave")    = 1
+
    list("Alice")   = 2
+
    list("Bob")     = 3
+
    list("Eve")     = 4
+
    list("Charlie") = 5
+

          
+
    ' インデックス・キー・値の一覧を表示
+
    For i As Integer = 0 To list.Count - 1
+
      Console.WriteLine("[{0}] {1,-8} => {2}", i, list.Keys(i), list.Values(i))
 
    Next
    Next
+
    Console.WriteLine()
 

        

        
~
    ' キー"Charlie"を持つ要素のインデックスを取得
    ' キー"baz"に該当する値を取得
~
    Console.WriteLine("IndexOfKey 'Charlie': {0}", list.IndexOfKey("Charlie"))
    Dim valueOfBaz As Integer
-

          
-
    If dict.TryGetValue("baz", valueOfBaz) Then
-
      Console.WriteLine("value of 'baz': {0}", valueOfBaz)
-
    Else
-
      Console.WriteLine("key not found")
-
    End If
 

        

        
~
    ' 値2を持つ要素のインデックスを取得
    ' キー"hoge"に該当する値を取得
~
    Console.WriteLine("IndexOfValue 2: {0}", list.IndexOfValue(2))
    Dim valueOfHoge As Integer
 

        

        
~
    ' 値42を持つ要素のインデックスを取得
    If dict.TryGetValue("hoge", valueOfHoge) Then
~
    Console.WriteLine("IndexOfValue 42: {0}", list.IndexOfValue(42))
      Console.WriteLine("value of 'hoge': {0}", valueOfHoge)
-
    Else
-
      Console.WriteLine("key not found")
-
    End If
 
  End Sub
  End Sub
 
End Class
End Class
 
}}
}}
 
#tabpage-end
#tabpage-end
 

        

        
 
#prompt(実行結果){{
#prompt(実行結果){{
~
[0] Alice    => 2
True
~
[1] Bob      => 3
False
~
[2] Charlie  => 5
baz => 42
~
[3] Dave     => 1
foo => 16
~
[4] Eve      => 4
value of 'baz': 42
-
key not found
-
}}
 

        

        
~
IndexOfKey 'Charlie': 2
SortedListクラスとSortedDictionaryクラスの違いの一つは、SortedListクラスがインデックスを指定したキー・値へのアクセスが出来るのに対し、SortedDictionaryクラスではインデックスを指定したアクセスは出来ない点です。 SortedDictionaryでは出来ず、SortedListでは出来る操作には次のような操作があります。
~
IndexOfValue 2: 0

          
~
IndexOfValue 42: -1
まず、&msdn(netfx,member,System.Collections.Generic.SortedList`2.Keys){Keysプロパティ};および&msdn(netfx,member,System.Collections.Generic.SortedList`2.Values){Valuesプロパティ};を参照することで、インデックスを指定して個々の要素のキーと値を取得できます。 これは、非ジェネリックなSortedListのGetByIndexメソッドに相当します。 ただ、インデックスを指定した値・キーの設定は出来ないため、SetByIndexメソッドに相当する操作はありません。 また、非ジェネリックなSortedListと同じく、&msdn(netfx,member,System.Collections.Generic.SortedList`2.IndexOfKey){IndexOfKeyメソッド};および&msdn(netfx,member,System.Collections.Generic.SortedList`2.IndexOfValue){IndexOfValueメソッド};を使うことで、キー・値が格納されている要素のインデックスを取得することが出来ます。 &msdn(netfx,member,System.Collections.Generic.SortedList`2.RemoveAt){RemoveAtメソッド};で、インデックスを指定して要素を削除することも出来ます。
+
}}
 

        

        
~
SortedListでは、Removeメソッドによるキーを指定した要素の削除の他に、&msdn(netfx,member,System.Collections.Generic.SortedList`2.RemoveAt){RemoveAtメソッド};によるインデックスを指定した要素の削除を行うことができます。
以下は、SortedListを使ってインデックスを指定した操作を行う例です。 いずれもSortedDictionaryでは出来ない操作です。
 

        

        
 
#tabpage(codelang=cs)
#tabpage(codelang=cs)
 
#code{{
#code{{
1053,17 349,22
 

        

        
 
    for (int i = 0; i < list.Count; i++)
    for (int i = 0; i < list.Count; i++)
 
    {
    {
~
      Console.WriteLine("[{0}] {1,-8} => {2}", i, list.Keys[i], list.Values[i]);
      // インデックスを指定してキーと値を取得
-
      Console.WriteLine("[{0}] {1} => {2}", i, list.Keys[i], list.Values[i]);
 
    }
    }
 

        

        
~
    Console.WriteLine();
    // キー"Charlie"を持つ要素のインデックスを取得
-
    Console.WriteLine("IndexOfKey 'Charlie': {0}", list.IndexOfKey("Charlie"));
-

          
-
    // 値2を持つ要素のインデックスを取得
-
    Console.WriteLine("IndexOfValue 2: {0}", list.IndexOfValue(2));
 

        

        
 
    // インデックス3の要素を削除
    // インデックス3の要素を削除
 
    list.RemoveAt(3);
    list.RemoveAt(3);
 

        

        
~
    for (int i = 0; i < list.Count; i++)
    foreach (KeyValuePair<string, int> pair in list)
 
    {
    {
~
      Console.WriteLine("[{0}] {1,-8} => {2}", i, list.Keys[i], list.Values[i]);
      Console.WriteLine("{0} => {1}", pair.Key, pair.Value);
 
    }
    }
 
  }
  }
 
}
}
1084,15 385,21
 
    list("Charlie") = 5
    list("Charlie") = 5
 

        

        
 
    For i As Integer = 0 To list.Count - 1
    For i As Integer = 0 To list.Count - 1
~
      Console.WriteLine("[{0}] {1,-8} => {2}", i, list.Keys(i), list.Values(i))
      ' インデックスを指定してキーと値を取得
-
      Console.WriteLine("[{0}] {1} => {2}", i, list.Keys(i), list.Values(i))
 
    Next
    Next
~
    Console.WriteLine()

          
-
    ' キー"Charlie"を持つ要素のインデックスを取得
-
    Console.WriteLine("IndexOfKey 'Charlie': {0}", list.IndexOfKey("Charlie"))
-

          
-
    ' 値2を持つ要素のインデックスを取得
-
    Console.WriteLine("IndexOfValue 2: {0}", list.IndexOfValue(2))
 

        

        
 
    ' インデックス3の要素を削除
    ' インデックス3の要素を削除
 
    list.RemoveAt(3)
    list.RemoveAt(3)
 

        

        
~
    For i As Integer = 0 To list.Count - 1
    For Each pair As KeyValuePair(Of String, Integer) In list
~
      Console.WriteLine("[{0}] {1,-8} => {2}", i, list.Keys(i), list.Values(i))
      Console.WriteLine("{0} => {1}", pair.Key, pair.Value)
 
    Next
    Next
 
  End Sub
  End Sub
 
End Class
End Class
1100,45 407,33
 
#tabpage-end
#tabpage-end
 

        

        
 
#prompt(実行結果){{
#prompt(実行結果){{
~
[0] Alice    => 2
[0] Alice => 2
~
[1] Bob      => 3
[1] Bob => 3
~
[2] Charlie  => 5
[2] Charlie => 5
~
[3] Dave     => 1
[3] Dave => 1
~
[4] Eve      => 4
[4] Eve => 4
~

          
IndexOfKey 'Charlie': 2
~
[0] Alice    => 2
IndexOfValue 2: 0
~
[1] Bob      => 3
Alice => 2
~
[2] Charlie  => 5
Bob => 3
~
[3] Eve      => 4
Charlie => 5
-
Eve => 4
 
}}
}}
 

        

        
~
*キー比較・ソート順のカスタマイズ [#SortedListSortedDictionary_SpecifyComparer]
**キー比較・ソート順のカスタマイズ [#SortedListSortedDictionary_SpecifyComparer]
~
SortedList・SortedDictionaryにはSortメソッドやReverseメソッドなどコレクションに格納されている要素の順序を並べ替えるメソッドは用意されていません。 そのため、一度インスタンスを作成すると後から並べ替え順序を変更することはできません。
[[Dictionary>programming/netfx/collections/2_generic_2_dictionary#Dictionary]]や[[非ジェネリックなSortedList>programming/netfx/collections/1_nongeneric_3_sortedlist#SortedList]]と同じく、コンストラクタで適切なIComparer<T>インターフェイスを指定することで、キー比較時およびソート時の動作をカスタマイズ出来ます。 以下は、大文字小文字を無視し、アルファベット順とは逆順(Z-Aの順)になるようにソートするIComparer<string>を実装し、SortedListおよびSortedDictionaryでの並べ替え順をカスタマイズする例です。
+

          
+
SortedList・SortedDictionaryでは、コンストラクタで適切な[[IComparer<T>インターフェイス>programming/netfx/comparison/0_comparison#IComparerOfT]]を指定することでキーの比較や並べ替え順序を独自に定義したものに変更することができます。
+

          
+
以下の例で使用するIComparer<T>インターフェイスなど、比較処理に関する詳細については以下のページも合わせてご覧ください。
+

          
+
-[[programming/netfx/comparison]]
+
--[[programming/netfx/comparison/0_comparison]]
+
-[[programming/netfx/sorting]]
+
--[[programming/netfx/sorting/0_basictypes]]
+
--[[programming/netfx/sorting/1_compositetypes]]
+

          
+
**独自の並べ替え順序を定義する
+
次の例は、並べ替えの順序を独自に定義してSortedList・SortedDictionaryでの並べ替え順をカスタマイズするものです。 大文字小文字の違いを無視し、アルファベット順とは逆順(Z→Aの順)になるようにソートするIComparer<string>を実装したクラスCaseInsensitiveReverseStringComparerを作成し、それをSortedList・SortedDictionaryのコンストラクタに指定することで独自に定義した並べ替え順序となるようにしています。
 

        

        
 
#tabpage(codelang=cs)
#tabpage(codelang=cs)
 
#code{{
#code{{
 
using System;
using System;
 
using System.Collections.Generic;
using System.Collections.Generic;
 

        

        
~
// 大文字小文字の違いを無視し、アルファベット順とは逆順にソートするためのIComparer
// 大文字小文字を無視し、アルファベット順とは逆順にソートするためのIComparer
 
class CaseInsensitiveReverseStringComparer : IComparer<string>
class CaseInsensitiveReverseStringComparer : IComparer<string>
 
{
{
 
  public int Compare(string x, string y)
  public int Compare(string x, string y)
 
  {
  {
~
    // StringComparer.CurrentCultureIgnoreCase.Compareの戻り値の符号を反転して逆順となるような結果を返す
    // StringComparer.CurrentCultureIgnoreCase.Compareとは逆の結果を返すようにする
 
    return -1 * StringComparer.CurrentCultureIgnoreCase.Compare(x, y);
    return -1 * StringComparer.CurrentCultureIgnoreCase.Compare(x, y);
 
  }
  }
 
}
}
1147,7 442,6
 
{
{
 
  static void Main()
  static void Main()
 
  {
  {
+
    // 独自に定義した並べ替え順序を実装するIComparerを指定してSortedListを作成
 
    SortedList<string, int> list = new SortedList<string, int>(new CaseInsensitiveReverseStringComparer());
    SortedList<string, int> list = new SortedList<string, int>(new CaseInsensitiveReverseStringComparer());
 

        

        
 
    list["Bob"]     = 1;
    list["Bob"]     = 1;
1161,10 455,9
 

        

        
 
    foreach (KeyValuePair<string, int> pair in list)
    foreach (KeyValuePair<string, int> pair in list)
 
    {
    {
~
      Console.WriteLine("{0,-8} => {1}", pair.Key, pair.Value);
      Console.WriteLine("{0} => {1}", pair.Key, pair.Value);
 
    }
    }
 

        

        
+
    // 独自に定義した並べ替え順序を実装するIComparerを指定してSortedDictionaryを作成
 
    SortedDictionary<string, int> dict = new SortedDictionary<string, int>(new CaseInsensitiveReverseStringComparer());
    SortedDictionary<string, int> dict = new SortedDictionary<string, int>(new CaseInsensitiveReverseStringComparer());
 

        

        
 
    dict["Bob"]     = 1;
    dict["Bob"]     = 1;
1178,7 471,7
 

        

        
 
    foreach (KeyValuePair<string, int> pair in dict)
    foreach (KeyValuePair<string, int> pair in dict)
 
    {
    {
~
      Console.WriteLine("{0,-8} => {1}", pair.Key, pair.Value);
      Console.WriteLine("{0} => {1}", pair.Key, pair.Value);
 
    }
    }
 
  }
  }
 
}
}
1188,19 481,18
 
Imports System
Imports System
 
Imports System.Collections.Generic
Imports System.Collections.Generic
 

        

        
~
' 大文字小文字の違いを無視し、アルファベット順とは逆順にソートするためのIComparer
' 大文字小文字を無視し、アルファベット順とは逆順にソートするためのIComparer
 
Class CaseInsensitiveReverseStringComparer
Class CaseInsensitiveReverseStringComparer
 
  Implements IComparer(Of String)
  Implements IComparer(Of String)
 

        

        
 
  Public Function Compare(ByVal x As String, ByVal y As String) As Integer Implements IComparer(Of String).Compare
  Public Function Compare(ByVal x As String, ByVal y As String) As Integer Implements IComparer(Of String).Compare
~
    ' StringComparer.CurrentCultureIgnoreCase.Compareの戻り値の符号を反転して逆順となるような結果を返す
    ' StringComparer.CurrentCultureIgnoreCase.Compareとは逆の結果を返すようにする
 
    Return -1 * StringComparer.CurrentCultureIgnoreCase.Compare(x, y)
    Return -1 * StringComparer.CurrentCultureIgnoreCase.Compare(x, y)
 
  End Function
  End Function
 
End Class
End Class
 

        

        
 
Class Sample
Class Sample
 
  Shared Sub Main()
  Shared Sub Main()
+
    ' 独自に定義した並べ替え順序を実装するIComparerを指定してSortedListを作成
 
    Dim list As New SortedList(Of String, Integer)(New CaseInsensitiveReverseStringComparer())
    Dim list As New SortedList(Of String, Integer)(New CaseInsensitiveReverseStringComparer())
 

        

        
 
    list("Bob")     = 1
    list("Bob")     = 1
1213,10 505,9
 
    Console.WriteLine("[SortedList]")
    Console.WriteLine("[SortedList]")
 

        

        
 
    For Each pair As KeyValuePair(Of String, Integer) In list
    For Each pair As KeyValuePair(Of String, Integer) In list
~
      Console.WriteLine("{0,-8} => {1}", pair.Key, pair.Value)
      Console.WriteLine("{0} => {1}", pair.Key, pair.Value)
 
    Next
    Next
 

        

        
+
    ' 独自に定義した並べ替え順序を実装するIComparerを指定してSortedDictionaryを作成
 
    Dim dict As New SortedDictionary(Of String, Integer)(New CaseInsensitiveReverseStringComparer())
    Dim dict As New SortedDictionary(Of String, Integer)(New CaseInsensitiveReverseStringComparer())
 

        

        
 
    dict("Bob")     = 1
    dict("Bob")     = 1
1229,7 520,7
 
    Console.WriteLine("[SortedDictionary]")
    Console.WriteLine("[SortedDictionary]")
 

        

        
 
    For Each pair As KeyValuePair(Of String, Integer) In dict
    For Each pair As KeyValuePair(Of String, Integer) In dict
~
      Console.WriteLine("{0,-8} => {1}", pair.Key, pair.Value)
      Console.WriteLine("{0} => {1}", pair.Key, pair.Value)
 
    Next
    Next
 
  End Sub
  End Sub
 
End Class
End Class
1238,442 529,23
 

        

        
 
#prompt(実行結果){{
#prompt(実行結果){{
 
[SortedList]
[SortedList]
~
Charlie  => 3
Charlie => 3
~
BOB      => 72
BOB => 72
~
aLiCe    => 16
aLiCe => 16
 
[SortedDictionary]
[SortedDictionary]
~
Charlie  => 3
Charlie => 3
~
Bob      => 72
Bob => 72
~
Alice    => 16
Alice => 16
+
}}
+

          
+
実行結果からもわかるように、大文字小文字の違いがあっても同一のキーとして扱われるようになるため、値は上書きされるようになります。
+

          
+
**降順・逆順にする
+
SortedList・SortedDictionaryにはReverseメソッドが用意されていないため、コレクションの内容を昇順から降順に並べ替え順序を変えることはできません。 並べ替え順序を変えるには新たに別のインスタンスを作成する必要があります。
+

          
+
次の例では、既存のSortedListのコピーを作成し、内容は同じで並べ替え順序だけを逆にしたインスタンスを作成することにより、逆順にしたSortedListを得ています。 新しいSortedListのインスタンスを作成する際、コンストラクタに既存のSortedListを指定することで同一の内容を持つインスタンスを作成します。 同時に、元のIComparer<T>とは逆の順序に並べ替えるようにしたIComparer<T>をコンストラクタに指定することで逆順に並べ替えるようにしています。
+

          
+
この例で紹介する方法では、&msdn(netfx,member,System.Collections.Generic.SortedList`2.Comparer){Comparerプロパティ};からIComparer<T>を取得することにより、個別に並べ替え順序を定義することなく単に並べ替え順序を逆にしています。 そのため、キーの型に関わらずどのようなSortedListでも逆順にすることができます。
+

          
+
#tabpage(codelang=cs)
+
#code{{
+
using System;
+
using System.Collections.Generic;
+

          
+
// 指定されたIComparer<T>と逆の順序に並べ替えるIComparer<T>の実装
+
class ReverseComparer<T> : IComparer<T>
+
{
+
  private IComparer<T> comparer;
+

          
+
  public ReverseComparer(IComparer<T> comparer)
+
  {
+
    this.comparer = comparer;
+
  }
+

          
+
  public int Compare(T x, T y)
+
  {
+
    // 指定する引数の順序を逆にすることで、元になったIComparer<T>とは逆の結果を返す
+
    return comparer.Compare(y, x);
+
  }
+
}
+

          
+
class Sample
+
{
+
  // 内容はそのままで並べ替え順序を逆にしたSortedListを作成するメソッド
+
  static SortedList<TKey, TValue> CreateReversed<TKey, TValue>(SortedList<TKey, TValue> source)
+
  {
+
    // コレクションの内容はsourceと同じもの、並べ替え順序はsource.Comparerで
+
    // 定義されているものとは逆となるようなインスタンスを返す
+
    return new SortedList<TKey, TValue>(source, new ReverseComparer<TKey>(source.Comparer));
+
  }
+

          
+
  static void Main()
+
  {
+
    // キーがstringのSortedList
+
    SortedList<string, int> list1 = new SortedList<string, int>();
+

          
+
    list1["Bob"]     = 1;
+
    list1["Alice"]   = 2;
+
    list1["Charlie"] = 3;
+

          
+
    // 逆順にしたものを作成し、内容を表示
+
    foreach (KeyValuePair<string, int> pair in CreateReversed(list1))
+
    {
+
      Console.WriteLine("{0,-8} => {1}", pair.Key, pair.Value);
+
    }
+
    Console.WriteLine();
+

          
+
    // キーがintのSortedList
+
    SortedList<int, string> list2 = new SortedList<int, string>();
+

          
+
    list2[2] = "Alice";
+
    list2[1] = "Bob";
+
    list2[3] = "Charlie";
+

          
+
    // 逆順にしたものを作成し、内容を表示
+
    foreach (KeyValuePair<int, string> pair in CreateReversed(list2))
+
    {
+
      Console.WriteLine("{0} => {1}", pair.Key, pair.Value);
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
' 指定されたIComparer<T>と逆の順序に並べ替えるIComparer<T>の実装
+
Class ReverseComparer(Of T)
+
  Implements IComparer(Of T)
+

          
+
  Private comparer As IComparer(Of T)
+

          
+
  Public Sub New(ByVal comparer As IComparer(Of T))
+
    Me.comparer = comparer
+
  End SUb
+

          
+
  Public Function Compare(ByVal x As T, ByVal y As T) As Integer Implements IComparer(Of T).Compare
+
    ' 指定する引数の順序を逆にすることで、元になったIComparer<T>とは逆の結果を返す
+
    Return comparer.Compare(y, x)
+
  End Function
+
End Class
+

          
+
Class Sample
+
  ' 内容はそのままで並べ替え順序を逆にしたSortedListを作成するメソッド
+
  Shared Function CreateReversed(Of TKey, TValue)(ByVal source As SortedList(Of TKey, TValue)) As SortedList(Of TKey, TValue)
+
    ' コレクションの内容はsourceと同じもの、並べ替え順序はsource.Comparerで
+
    ' 定義されているものとは逆となるようなインスタンスを返す
+
    Return New SortedList(Of TKey, TValue)(source, New ReverseComparer(Of TKey)(source.Comparer))
+
  End Function
+

          
+
  Shared Sub Main()
+
    ' キーがstringのSortedList
+
    Dim list1 As New SortedList(Of String, Integer)()
+

          
+
    list1("Bob")     = 1
+
    list1("Alice")   = 2
+
    list1("Charlie") = 3
+

          
+
    ' 逆順にしたものを作成し、内容を表示
+
    For Each pair As KeyValuePair(Of String, Integer) In CreateReversed(list1)
+
      Console.WriteLine("{0,-8} => {1}", pair.Key, pair.Value)
+
    Next
+
    Console.WriteLine()
+

          
+
    ' キーがintのSortedList
+
    Dim list2 As New SortedList(Of Integer, String)()
+

          
+
    list2(2) = "Alice"
+
    list2(1) = "Bob"
+
    list2(3) = "Charlie"
+

          
+
    ' 逆順にしたものを作成し、内容を表示
+
    For Each pair As KeyValuePair(Of Integer, String) In CreateReversed(list2)
+
      Console.WriteLine("{0} => {1}", pair.Key, pair.Value)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
Charlie  => 3
+
Bob      => 1
+
Alice    => 2
+

          
+
3 => Charlie
+
2 => Alice
+
1 => Bob
+
}}
+

          
+
この方法は、SortedDictionaryでも同様に実装することができます。
+

          
+
また、既存のSortedList・SortedDictionaryを降順にするのではなく、降順に並べ替えるSortedList・SortedDictionaryを作成したい場合は、先の例のReverseComparerをコンストラクタに指定します。
+

          
+
#tabpage(codelang=cs)
+
#code{{
+
using System;
+
using System.Collections.Generic;
+

          
+
// 指定されたIComparer<T>と逆の順序に並べ替えるIComparer<T>の実装
+
class ReverseComparer<T> : IComparer<T>
+
{
+
  private IComparer<T> comparer;
+

          
+
  public ReverseComparer(IComparer<T> comparer)
+
  {
+
    this.comparer = comparer;
+
  }
+

          
+
  public int Compare(T x, T y)
+
  {
+
    // 指定する引数の順序を逆にすることで、元になったIComparer<T>とは逆の結果を返す
+
    return comparer.Compare(y, x);
+
  }
+
}
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    // キーがstringで、降順に並べ替えるSortedListを作成する
+
    IComparer<string> descendingStringComparer = new ReverseComparer<string>(Comparer<string>.Default);
+
    SortedList<string, int> list1 = new SortedList<string, int>(descendingStringComparer);
+

          
+
    list1["Bob"]     = 1;
+
    list1["Alice"]   = 2;
+
    list1["Charlie"] = 3;
+

          
+
    // 内容を表示
+
    foreach (KeyValuePair<string, int> pair in list1)
+
    {
+
      Console.WriteLine("{0,-8} => {1}", pair.Key, pair.Value);
+
    }
+
    Console.WriteLine();
+

          
+
    // キーがintで、降順に並べ替えるSortedListを作成する
+
    IComparer<int> descendingIntComparer = new ReverseComparer<int>(Comparer<int>.Default);
+
    SortedList<int, string> list2 = new SortedList<int, string>(descendingIntComparer);
+

          
+
    list2[2] = "Alice";
+
    list2[1] = "Bob";
+
    list2[3] = "Charlie";
+

          
+
    // 内容を表示
+
    foreach (KeyValuePair<int, string> pair in list2)
+
    {
+
      Console.WriteLine("{0} => {1}", pair.Key, pair.Value);
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
' 指定されたIComparer<T>と逆の順序に並べ替えるIComparer<T>の実装
+
Class ReverseComparer(Of T)
+
  Implements IComparer(Of T)
+

          
+
  Private comparer As IComparer(Of T)
+

          
+
  Public Sub New(ByVal comparer As IComparer(Of T))
+
    Me.comparer = comparer
+
  End SUb
+

          
+
  Public Function Compare(ByVal x As T, ByVal y As T) As Integer Implements IComparer(Of T).Compare
+
    ' 指定する引数の順序を逆にすることで、元になったIComparer<T>とは逆の結果を返す
+
    Return comparer.Compare(y, x)
+
  End Function
+
End Class
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' キーがStringで、降順に並べ替えるSortedListを作成する
+
    Dim descendingStringComparer As New ReverseComparer(Of String)(Comparer(Of String).Default)
+
    Dim list1 As New SortedList(Of String, Integer)(descendingStringComparer)
+

          
+
    list1("Bob")     = 1
+
    list1("Alice")   = 2
+
    list1("Charlie") = 3
+

          
+
    ' 内容を表示
+
    For Each pair As KeyValuePair(Of String, Integer) In list1
+
      Console.WriteLine("{0,-8} => {1}", pair.Key, pair.Value)
+
    Next
+
    Console.WriteLine()
+

          
+
    ' キーがIntegerで、降順に並べ替えるSortedListを作成する
+
    Dim descendingIntComparer As New ReverseComparer(Of Integer)(Comparer(Of Integer).Default)
+
    Dim list2 As New SortedList(Of Integer, String)(descendingIntComparer)
+

          
+
    list2(2) = "Alice"
+
    list2(1) = "Bob"
+
    list2(3) = "Charlie"
+

          
+
    ' 内容を表示
+
    For Each pair As KeyValuePair(Of Integer, String) In list2
+
      Console.WriteLine("{0} => {1}", pair.Key, pair.Value)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
Charlie  => 3
+
Bob      => 1
+
Alice    => 2
+

          
+
3 => Charlie
+
2 => Alice
+
1 => Bob
+
}}
+

          
+

          
+
**キーに独自型を使用する
+
構造体やクラスなど、独自に定義した型をSortedList・SortedDictionaryのキーとする場合は、その型の比較を行うIComparer<T>を用意しなければ並べ替えを行うことができません。 次の例は、構造体をキーとしたSortedListを作成・使用する例です。 SortedListだけでなくSortedDictionaryの場合にも適用できます。
+

          
+
#tabpage(codelang=cs)
+
#code{{
+
using System;
+
using System.Collections.Generic;
+

          
+
// SortedListのキーとして使用する構造体
+
struct Account
+
{
+
  public string Name;
+
  public int ID;
+

          
+
  public Account(string name, int id)
+
  {
+
    Name = name;
+
    ID = id;
+
  }
+
}
+

          
+
// Account構造体のNameフィールドで並べ替えを行うIComparer<T>
+
class AccountNameComparer : IComparer<Account>
+
{
+
  public int Compare(Account x, Account y)
+
  {
+
    return string.Compare(x.Name, y.Name);
+
  }
+
}
+

          
+
// Account構造体のIDフィールドで並べ替えを行うIComparer<T>
+
class AccountIDComparer : IComparer<Account>
+
{
+
  public int Compare(Account x, Account y)
+
  {
+
    return x.ID - y.ID;
+
  }
+
}
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    // キーにAccount構造体を使用し、Nameフィールドに従って並べ替えるSortedList
+
    SortedList<Account, string> list1 = new SortedList<Account, string>(new AccountNameComparer());
+

          
+
    list1[new Account("Bob", 1)]      = "bob@example.com";
+
    list1[new Account("Charlie", 3)]  = "charlie@example.net";
+
    list1[new Account("Alice", 2)]    = "alice@mail.example.net";
+

          
+
    // 内容を表示
+
    foreach (KeyValuePair<Account, string> pair in list1)
+
    {
+
      Console.WriteLine("{0}:{1,-8} => {2}", pair.Key.ID, pair.Key.Name, pair.Value);
+
    }
+
    Console.WriteLine();
+

          
+
    // キーにAccount構造体を使用し、IDフィールドに従って並べ替えるSortedList
+
    SortedList<Account, string> list2 = new SortedList<Account, string>(new AccountIDComparer());
+

          
+
    list2[new Account("Bob", 1)]      = "bob@example.com";
+
    list2[new Account("Charlie", 3)]  = "charlie@example.net";
+
    list2[new Account("Alice", 2)]    = "alice@mail.example.net";
+

          
+
    // 内容を表示
+
    foreach (KeyValuePair<Account, string> pair in list2)
+
    {
+
      Console.WriteLine("{0}:{1,-8} => {2}", pair.Key.ID, pair.Key.Name, pair.Value);
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
' SortedListのキーとして使用する構造体
+
Structure Account
+
  Public Name As String
+
  Public ID As Integer
+

          
+
  Public Sub New(ByVal name As String, ByVal id As Integer)
+
    Me.Name = name
+
    Me.ID = id
+
  End Sub
+
End Structure
+

          
+
' Account構造体のNameフィールドで並べ替えを行うIComparer(Of T)
+
Class AccountNameComparer
+
  Implements IComparer(Of Account)
+

          
+
  Public Function Compare(ByVal x As Account, ByVal y As Account) As Integer Implements IComparer(Of Account).Compare
+
    Return String.Compare(x.Name, y.Name)
+
  End Function
+
End Class
+

          
+
' Account構造体のIDフィールドで並べ替えを行うIComparer(Of T)
+
Class AccountIDComparer
+
  Implements IComparer(Of Account)
+

          
+
  Public Function Compare(ByVal x As Account, ByVal y As Account) As Integer Implements IComparer(Of Account).Compare
+
    Return x.ID - y.ID
+
  End Function
+
End Class
+

          
+
Class Sample
+
  Shared Sub Main()
+
    ' キーにAccount構造体を使用し、Nameフィールドに従って並べ替えるSortedList
+
    Dim list1 As New SortedList(Of Account, String)(New AccountNameComparer())
+

          
+
    list1(New Account("Bob", 1))      = "bob@example.com"
+
    list1(New Account("Charlie", 3))  = "charlie@example.net"
+
    list1(New Account("Alice", 2))    = "alice@mail.example.net"
+

          
+
    ' 内容を表示
+
    For Each pair As KeyValuePair(Of Account, String) In list1
+
      Console.WriteLine("{0}:{1,-8} => {2}", pair.Key.ID, pair.Key.Name, pair.Value)
+
    Next
+
    Console.WriteLine()
+

          
+
    ' キーにAccount構造体を使用し、IDフィールドに従って並べ替えるSortedList
+
    Dim list2 As New SortedList(Of Account, String)(New AccountIDComparer())
+

          
+
    list2(New Account("Bob", 1))      = "bob@example.com"
+
    list2(New Account("Charlie", 3))  = "charlie@example.net"
+
    list2(New Account("Alice", 2))    = "alice@mail.example.net"
+

          
+
    ' 内容を表示
+
    For Each pair As KeyValuePair(Of Account, String) In list2
+
      Console.WriteLine("{0}:{1,-8} => {2}", pair.Key.ID, pair.Key.Name, pair.Value)
+
    Next
+
  End Sub
+
End Class
 
}}
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
2:Alice    => alice@mail.example.net
+
1:Bob      => bob@example.com
+
3:Charlie  => charlie@example.net
+

          
+
1:Bob      => bob@example.com
+
2:Alice    => alice@mail.example.net
+
3:Charlie  => charlie@example.net
+
}}
+

          
+
独自型のIComparer<T>を実装する方法の詳細については[[programming/netfx/sorting/1_compositetypes]]や[[programming/netfx/comparison/0_comparison]]を参照してください。
+

          
+

          
+
*パフォーマンスの違い [#performance]
+
SortedListクラスとSortedDictionaryクラスでは、内部で使用されるデータ構造の違いから使用するメモリの量と挿入・削除の速度にも違いがあらわれます。 &msdn(netfx,id,5z658b67){Sorted コレクション型};によると、両者の違いは次のようになっています。
+

          
+
|*SortedListとSortedDictionaryの相違点&br;(&var{n};はコレクション内の要素数)
+
|~相違点|~SortedList|~SortedDictionary|h
+
|~取得操作の速度|>|CENTER:O(log &var{n};)|
+
|~挿入操作・削除操作の速度|CENTER:一般にO(&var{n};)|CENTER:常にO(log &var{n};)|
+
|~使用するメモリ量|CENTER:比較して少ない|CENTER:比較して多い|
 

        

        
~
SortedListでは、新しい要素が末尾に挿入される場合(挿入の際に並べ替えが発生せず、かつ挿入により内部コレクションのサイズが変わらない場合)、挿入操作の速度は O(1) となります。
**パフォーマンスの違い
-
SortedListクラスとSortedDictionaryクラスのもう一つの違いは、使用するメモリの量と挿入・削除の速度です。 SortedListクラスとSortedDictionaryクラスはほとんどの操作は同じですが、インデックスによる操作をサポートするかどうかの実装の違いに起因して、パフォーマンスにも違いが現れます。 &msdn(netfx,id,5z658b67){Sorted コレクション型};によると、両者の違いは次のようになっています。
-

          
-
|*SortedListとSortedDictionaryの相違点&br;(nはコレクション内の要素数)
-
|~相違点|~System.Collections.Generic.SortedList&br;System.Collections.SortedList|~System.Collections.Generic.SortedDictionary|h
-
|~取得の速度|>|どちらもO(log n)|
-
|~挿入・削除の速度|一般にO(n)&br;挿入による並べ替えが発生せず、かつ挿入により内部コレクションのサイズが変わらない場合は、新しい要素が末尾に挿入されるためO(1)|常にO(log n)|
-
|~使用するメモリ量|比較して少ない|比較して多い|
 

        

        
 
以下は、互いに重複しないシャッフルされたキーを使って要素を追加した場合の速度を比較した結果の一例です。
以下は、互いに重複しないシャッフルされたキーを使って要素を追加した場合の速度を比較した結果の一例です。