2012-01-09T14:34:39の更新内容

programming/netfx/sorting/0_basictypes/index.wiki.txt

current previous
4,7 4,7
 

        

        
 
#navi(..)
#navi(..)
 

        

        
~
ここでは配列・List・Dictionaryなどの各種コレクションを使ったデータの並べ替え、コレクションのソート方法について見ていきます。 なお、まずは数値・文字列等の単純型(基本型)を格納する配列・コレクションのソートについてのみ説明します。 基本型のデフォルトのソート順については[[programming/netfx/sorting/0_basictypes_1_defaultsortorder]]、複合型を格納している配列・コレクションのソートについては[[programming/netfx/sorting/1_compositetypes]]、ジャグ配列・多次元配列のソートについては[[programming/netfx/sorting/2_arrays]]で順次解説します。
ここでは配列・List・Dictionaryなどの各種コレクションを使ったデータの並べ替え、コレクションのソート方法について見ていきます。 なお、まずは数値・文字列等の単純型(基本型)を格納する配列・コレクションのソートについてのみ説明します。 複合型を格納している配列・コレクションのソートについては[[programming/netfx/sorting/1_compositetypes]]、ジャグ配列・多次元配列のソートについては[[programming/netfx/sorting/2_arrays]]で順次解説します。
 

        

        
 
-関連するページ
-関連するページ
 
--[[programming/netfx/comparison]]
--[[programming/netfx/comparison]]
1518,6 1518,130
 

        

        
 
その他のシャッフルの実装例については[[programming/tips/shuffle_array]]、より適切な乱数の取得については[[programming/netfx/mathematics/1_random]]、IComparer<T>については[[programming/netfx/comparison/0_comparison]]を参照してください。
その他のシャッフルの実装例については[[programming/tips/shuffle_array]]、より適切な乱数の取得については[[programming/netfx/mathematics/1_random]]、IComparer<T>については[[programming/netfx/comparison/0_comparison]]を参照してください。
 

        

        
-
*大文字小文字の違いを考慮したソート
-
文字列をソートする際、場合によっては大文字小文字の違いをどう扱うか厳密に決める必要が出て来ます。 その場合は、&msdn(netfx,type,System.StringComparer){StringComparer};を使ってどう扱うかを指定することができます。 Sortメソッド、OrderByメソッドともにIComparerを引数に取ることができ、これにStringComparerを指定することで、文字列比較の際の動作を指定できます。
-

          
-
#tabpage(C#)
-
#code(cs,Sort + IComparer){{
-
using System;
-
using System.Collections.Generic;
-

          
-
class Sample {
-
  static void Main()
-
  {
-
    List<string> list = new List<string>(new string[] {
-
      "ab", "ABC", "AA", "a", "aa", "abc", "A",
-
    });
-

          
-
    // 大文字・小文字の違いを無視してソート
-
    list.Sort(StringComparer.OrdinalIgnoreCase);
-

          
-
    foreach (string s in list) {
-
      Console.Write("{0} ", s);
-
    }
-
    Console.WriteLine();
-

          
-
    // 大文字・小文字の違いを意識してソート
-
    list.Sort(StringComparer.Ordinal);
-

          
-
    foreach (string s in list) {
-
      Console.Write("{0} ", s);
-
    }
-
    Console.WriteLine();
-
  }
-
}
-
}}
-

          
-
#code(cs,OrderBy + IComparer){{
-
using System;
-
using System.Collections.Generic;
-
using System.Linq;
-

          
-
class Sample {
-
  static void Main()
-
  {
-
    List<string> list = new List<string>(new string[] {
-
      "ab", "ABC", "AA", "a", "aa", "abc", "A",
-
    });
-

          
-
    // 大文字・小文字の違いを無視してソート
-
    foreach (string s in list.OrderBy(s => s, StringComparer.OrdinalIgnoreCase)) {
-
      Console.Write("{0} ", s);
-
    }
-
    Console.WriteLine();
-

          
-
    // 大文字・小文字の違いを意識してソート
-
    foreach (string s in list.OrderBy(s => s, StringComparer.Ordinal)) {
-
      Console.Write("{0} ", s);
-
    }
-
    Console.WriteLine();
-
  }
-
}
-
}}
-
#tabpage(VB)
-
#code(vb,Sort + IComparer){{
-
Imports System
-
Imports System.Collections.Generic
-

          
-
Class Sample
-
  Shared Sub Main()
-
    Dim list As New List(Of String)(New String() { _
-
      "ab", "ABC", "AA", "a", "aa", "abc", "A" _
-
    })
-

          
-
    ' 大文字・小文字の違いを無視してソート
-
    list.Sort(StringComparer.OrdinalIgnoreCase)
-

          
-
    For Each s As String In list
-
      Console.Write("{0} ", s)
-
    Next
-
    Console.WriteLine()
-

          
-
    ' 大文字・小文字の違いを意識してソート
-
    list.Sort(StringComparer.Ordinal)
-

          
-
    For Each s As String In list
-
      Console.Write("{0} ", s)
-
    Next
-
    Console.WriteLine()
-
  End Sub
-
End Class
-
}}
-

          
-
#code(vb,OrderBy + IComparer){{
-
Imports System
-
Imports System.Collections.Generic
-
Imports System.Linq
-

          
-
Class Sample
-
  Shared Sub Main()
-
    Dim list As New List(Of String)(New String() { _
-
      "ab", "ABC", "AA", "a", "aa", "abc", "A" _
-
    })
-

          
-
    ' 大文字・小文字の違いを無視してソート
-
    For Each str As String In list.OrderBy(Function(s) s, StringComparer.OrdinalIgnoreCase)
-
      Console.Write("{0} ", str)
-
    Next
-
    Console.WriteLine()
-

          
-
    ' 大文字・小文字の違いを意識してソート
-
    For Each str As String In list.OrderBy(Function(s) s, StringComparer.Ordinal)
-
      Console.Write("{0} ", str)
-
    Next
-
    Console.WriteLine()
-
  End Sub
-
End Class
-
}}
-
#tabpage-end
-

          
-
#prompt(実行結果){{
-
a A aa AA ab abc ABC 
-
A AA ABC a aa ab abc 
-
}}
-

          
-
なお、IComparerについては[[programming/netfx/comparison/0_comparison]]、StringComparerについて[[programming/netfx/string/2_2_compareoptions]]で詳しく解説しています。
-

          
 

        

        
 

        

        
 
*パフォーマンスの比較
*パフォーマンスの比較

programming/netfx/sorting/0_basictypes_1_defaultsortorder/index.wiki.txt

current previous
1,657 0,0
+
${smdncms:title,基本型とデフォルトのソート順}
+
${smdncms:keywords,ソート順,整数型,数値型,DateTime,DateTimeOffset,列挙型,列挙体}
+
${smdncms:document_versions,codelang=cs,codelang=vb}
+

          
+
#navi(..)
+

          
+
ここでは基本型のデフォルトのソート順について見てみます。 int, long等の数値型やDateTime等の型は&msdn(netfx,type,System.IComparable){IComparableインターフェイス};を実装していて、デフォルトではそれによって定義される順で並べ替えが行われます。
+

          
+
-関連するページ
+
--[[programming/netfx/comparison]]
+
---[[programming/netfx/comparison/0_comparison]]
+
--[[programming/netfx/enum]]
+

          
+
#googleadunit(banner)
+

          
+
*数値型 [#DefaultSortOrder_Numerics]
+
int, long, uint, byte等の整数型、float, double, decimal等の実数型は、いずれもその数の小さい順に並べ替えられます。 float, doubleの場合、NaN(非数)は-∞(負の無限大)や他の数よりも小さいと扱われる点に注意が必要です。
+

          
+
#prompt(実行結果){{
+
int: -2147483648, -1, 0, 1, 2147483647, 
+
double: NaN, -Infinity, -1.79769313486232E+308, -1, -0.01, 0, 0.01, 1, 1.79769313486232E+308, Infinity, 
+
decimal: -79228162514264337593543950335, -1, -0.01, 0, 0.01, 1, 79228162514264337593543950335, 
+
}}
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    int[] intArray = new int[] {0, 1, -1, int.MaxValue, int.MinValue};
+
    double[] doubleArray = new double[] {
+
      0.0, 1.0, -1.0, 0.01, -0.01,
+
      double.MaxValue, double.MinValue,
+
      double.PositiveInfinity, double.NegativeInfinity, double.NaN,
+
    };
+
    decimal[] decimalArray = new decimal[] {
+
      0m, 1m, -1m, 0.01m, -0.01m,
+
      decimal.MaxValue, decimal.MinValue,
+
    };
+

          
+
    Array.Sort(intArray);
+
    Array.Sort(doubleArray);
+
    Array.Sort(decimalArray);
+

          
+
    Console.Write("int: ");
+
    foreach (int val in intArray) {
+
      Console.Write("{0}, ", val);
+
    }
+
    Console.WriteLine();
+

          
+
    Console.Write("double: ");
+
    foreach (double val in doubleArray) {
+
      Console.Write("{0}, ", val);
+
    }
+
    Console.WriteLine();
+

          
+
    Console.Write("decimal: ");
+
    foreach (decimal val in decimalArray) {
+
      Console.Write("{0}, ", val);
+
    }
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim intArray As Integer() = New Integer() {0, 1, -1, Integer.MaxValue, Integer.MinValue}
+
    Dim doubleArray As Double() = New Double() { _
+
      0.0, 1.0, -1.0, 0.01, -0.01, _
+
      double.MaxValue, double.MinValue, _
+
      double.PositiveInfinity, double.NegativeInfinity, double.NaN _
+
    }
+
    Dim decimalArray As Decimal() = New Decimal() { _
+
      0D, 1D, -1D, 0.01D, -0.01D, _
+
      Decimal.MaxValue, Decimal.MinValue _
+
    }
+

          
+
    Array.Sort(intArray)
+
    Array.Sort(doubleArray)
+
    Array.Sort(decimalArray)
+

          
+
    Console.Write("Integer: ")
+
    For Each val As Integer In intArray
+
      Console.Write("{0}, ", val)
+
    Next
+
    Console.WriteLine()
+

          
+
    Console.Write("Double: ")
+
    For Each val As Double In doubleArray
+
      Console.Write("{0}, ", val)
+
    Next
+
    Console.WriteLine()
+

          
+
    Console.Write("Decimal: ")
+
    For Each val As Decimal In decimalArray
+
      Console.Write("{0}, ", val)
+
    Next
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
*文字列型 [#DefaultSortOrder_String]
+
文字列型では、辞書順(文字の順、長さの短い順)に並べ替えられます。
+

          
+
#prompt(実行結果){{
+
a
+
aa
+
aaa
+
aaaa
+
aab
+
aac
+
ab
+
aba
+
abb
+
ac
+
}}
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    string[] arr = new string[] {
+
      "a", "aa", "ab", "ac", "aaa", "aab", "aba", "abb", "aac", "aaaa",
+
    };
+

          
+
    Array.Sort(arr);
+

          
+
    foreach (string val in arr) {
+
      Console.WriteLine(val);
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim arr As String() = New String() { _
+
      "a", "aa", "ab", "ac", "aaa", "aab", "aba", "abb", "aac", "aaaa" _
+
    }
+

          
+
    Array.Sort(arr)
+

          
+
    For Each val As String In arr
+
      Console.WriteLine(val)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
ただ、カルチャや比較方法によっては単なる辞書順にはならないので注意してください。 詳しくは[[programming/netfx/string/2_2_compareoptions]]や[[programming/netfx/locale/1_infoes]]で解説しています。
+

          
+
**大文字小文字の違いを考慮したソート
+
文字列をソートする際、場合によっては大文字小文字の違いをどう扱うか厳密に決める必要が出て来ます。 その場合は、&msdn(netfx,type,System.StringComparer){StringComparer};を使ってどう扱うかを指定することができます。 Sortメソッド、OrderByメソッドともにIComparerを引数に取ることができ、これにStringComparerを指定することで、文字列比較の際の動作を指定できます。
+

          
+
#tabpage(C#)
+
#code(cs,Sort + IComparer){{
+
using System;
+
using System.Collections.Generic;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    List<string> list = new List<string>(new string[] {
+
      "ab", "ABC", "AA", "a", "aa", "abc", "A",
+
    });
+

          
+
    // 大文字・小文字の違いを無視してソート
+
    list.Sort(StringComparer.OrdinalIgnoreCase);
+

          
+
    foreach (string s in list) {
+
      Console.Write("{0} ", s);
+
    }
+
    Console.WriteLine();
+

          
+
    // 大文字・小文字の違いを意識してソート
+
    list.Sort(StringComparer.Ordinal);
+

          
+
    foreach (string s in list) {
+
      Console.Write("{0} ", s);
+
    }
+
    Console.WriteLine();
+
  }
+
}
+
}}
+

          
+
#code(cs,OrderBy + IComparer){{
+
using System;
+
using System.Collections.Generic;
+
using System.Linq;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    List<string> list = new List<string>(new string[] {
+
      "ab", "ABC", "AA", "a", "aa", "abc", "A",
+
    });
+

          
+
    // 大文字・小文字の違いを無視してソート
+
    foreach (string s in list.OrderBy(s => s, StringComparer.OrdinalIgnoreCase)) {
+
      Console.Write("{0} ", s);
+
    }
+
    Console.WriteLine();
+

          
+
    // 大文字・小文字の違いを意識してソート
+
    foreach (string s in list.OrderBy(s => s, StringComparer.Ordinal)) {
+
      Console.Write("{0} ", s);
+
    }
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb,Sort + IComparer){{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim list As New List(Of String)(New String() { _
+
      "ab", "ABC", "AA", "a", "aa", "abc", "A" _
+
    })
+

          
+
    ' 大文字・小文字の違いを無視してソート
+
    list.Sort(StringComparer.OrdinalIgnoreCase)
+

          
+
    For Each s As String In list
+
      Console.Write("{0} ", s)
+
    Next
+
    Console.WriteLine()
+

          
+
    ' 大文字・小文字の違いを意識してソート
+
    list.Sort(StringComparer.Ordinal)
+

          
+
    For Each s As String In list
+
      Console.Write("{0} ", s)
+
    Next
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+

          
+
#code(vb,OrderBy + IComparer){{
+
Imports System
+
Imports System.Collections.Generic
+
Imports System.Linq
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim list As New List(Of String)(New String() { _
+
      "ab", "ABC", "AA", "a", "aa", "abc", "A" _
+
    })
+

          
+
    ' 大文字・小文字の違いを無視してソート
+
    For Each str As String In list.OrderBy(Function(s) s, StringComparer.OrdinalIgnoreCase)
+
      Console.Write("{0} ", str)
+
    Next
+
    Console.WriteLine()
+

          
+
    ' 大文字・小文字の違いを意識してソート
+
    For Each str As String In list.OrderBy(Function(s) s, StringComparer.Ordinal)
+
      Console.Write("{0} ", str)
+
    Next
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
a A aa AA ab abc ABC 
+
A AA ABC a aa ab abc 
+
}}
+

          
+
なお、IComparerについては[[programming/netfx/comparison/0_comparison]]、StringComparerについて[[programming/netfx/string/2_2_compareoptions]]で詳しく解説しています。
+

          
+

          
+

          
+
*日付型 [#DefaultSortOrder_DateTime]
+
DateTimeとDateTimeOffsetは日付・時間の古い順に並べ替えられます。 並べ替えに際して、DateTimeでは&msdn(netfx,member,System.DateTime.Kind){Kindプロパティ};の値は無視されて日時のみが比較され、DateTimeOffsetでは日時に加えて&msdn(netfx,member,System.DateTimeOffset.Offset){Offsetプロパティ};の値が考慮されて比較される点に注意が必要です。 DateTimeの場合、現地時刻・UTCのいずれかに統一してからソートしないと意図しない結果になる場合があります。
+

          
+
#prompt(実行結果){{
+
DateTime
+
2000-01-01T00:00:00.0000000Z        (2000-01-01T00:00:00.0000000Z)
+
2000-01-01T00:00:00.0000000+09:00   (1999-12-31T15:00:00.0000000Z)
+
2000-01-01T06:00:00.0000000Z        (2000-01-01T06:00:00.0000000Z)
+
2000-01-01T18:00:00.0000000Z        (2000-01-01T18:00:00.0000000Z)
+
2000-01-02T00:00:00.0000000Z        (2000-01-02T00:00:00.0000000Z)
+
2000-01-02T00:00:00.0000000+09:00   (2000-01-01T15:00:00.0000000Z)
+
DateTimeOffset
+
2000-01-01T00:00:00.0000000+09:00   (1999-12-31T15:00:00.0000000+00:00)
+
2000-01-01T00:00:00.0000000+00:00   (2000-01-01T00:00:00.0000000+00:00)
+
2000-01-01T00:00:00.0000000-05:00   (2000-01-01T05:00:00.0000000+00:00)
+
2000-01-02T00:00:00.0000000+09:00   (2000-01-01T15:00:00.0000000+00:00)
+
2000-01-02T00:00:00.0000000+00:00   (2000-01-02T00:00:00.0000000+00:00)
+
2000-01-02T00:00:00.0000000-05:00   (2000-01-02T05:00:00.0000000+00:00)
+
}}
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    DateTime[] dateTimeArray = new DateTime[] {
+
      new DateTime(2000, 1, 1,  0, 0, 0, DateTimeKind.Local),
+
      new DateTime(2000, 1, 1,  0, 0, 0, DateTimeKind.Utc),
+
      new DateTime(2000, 1, 1,  6, 0, 0, DateTimeKind.Utc),
+
      new DateTime(2000, 1, 1, 18, 0, 0, DateTimeKind.Utc),
+
      new DateTime(2000, 1, 2,  0, 0, 0, DateTimeKind.Local),
+
      new DateTime(2000, 1, 2,  0, 0, 0, DateTimeKind.Utc),
+
    };
+
    DateTimeOffset[] dateTimeOffsetArray = new DateTimeOffset[] {
+
      new DateTimeOffset(2000, 1, 1, 0, 0, 0, new TimeSpan( 0, 0, 0)),
+
      new DateTimeOffset(2000, 1, 1, 0, 0, 0, new TimeSpan(-5, 0, 0)),
+
      new DateTimeOffset(2000, 1, 1, 0, 0, 0, new TimeSpan(+9, 0, 0)),
+
      new DateTimeOffset(2000, 1, 2, 0, 0, 0, new TimeSpan( 0, 0, 0)),
+
      new DateTimeOffset(2000, 1, 2, 0, 0, 0, new TimeSpan(-5, 0, 0)),
+
      new DateTimeOffset(2000, 1, 2, 0, 0, 0, new TimeSpan(+9, 0, 0)),
+
    };
+

          
+
    Array.Sort(dateTimeArray);
+
    Array.Sort(dateTimeOffsetArray);
+

          
+
    Console.WriteLine("DateTime");
+
    foreach (DateTime val in dateTimeArray) {
+
      Console.WriteLine("{0,-35:o} ({1:o})", val, val.ToUniversalTime());
+
    }
+

          
+
    Console.WriteLine("DateTimeOffset");
+
    foreach (DateTimeOffset val in dateTimeOffsetArray) {
+
      Console.WriteLine("{0,-35:o} ({1:o})", val, val.ToUniversalTime());
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim dateTimeArray As DateTime() = New DateTime() { _
+
      New DateTime(2000, 1, 1,  0, 0, 0, DateTimeKind.Local), _
+
      New DateTime(2000, 1, 1,  0, 0, 0, DateTimeKind.Utc), _
+
      New DateTime(2000, 1, 1,  6, 0, 0, DateTimeKind.Utc), _
+
      New DateTime(2000, 1, 1, 18, 0, 0, DateTimeKind.Utc), _
+
      New DateTime(2000, 1, 2,  0, 0, 0, DateTimeKind.Local), _
+
      New DateTime(2000, 1, 2,  0, 0, 0, DateTimeKind.Utc) _
+
    }
+
    Dim dateTimeOffsetArray As DateTimeOffset() = New DateTimeOffset() { _
+
      New DateTimeOffset(2000, 1, 1, 0, 0, 0, new TimeSpan( 0, 0, 0)), _
+
      New DateTimeOffset(2000, 1, 1, 0, 0, 0, new TimeSpan(-5, 0, 0)), _
+
      New DateTimeOffset(2000, 1, 1, 0, 0, 0, new TimeSpan(+9, 0, 0)), _
+
      New DateTimeOffset(2000, 1, 2, 0, 0, 0, new TimeSpan( 0, 0, 0)), _
+
      New DateTimeOffset(2000, 1, 2, 0, 0, 0, new TimeSpan(-5, 0, 0)), _
+
      new DateTimeOffset(2000, 1, 2, 0, 0, 0, new TimeSpan(+9, 0, 0)) _
+
    }
+

          
+
    Array.Sort(dateTimeArray)
+
    Array.Sort(dateTimeOffsetArray)
+

          
+
    Console.WriteLine("DateTime")
+
    For Each val As DateTime In dateTimeArray
+
      Console.WriteLine("{0,-35:o} ({1:o})", val, val.ToUniversalTime())
+
    Next
+

          
+
    Console.WriteLine("DateTimeOffset")
+
    For Each val As DateTimeOffset In dateTimeOffsetArray
+
      Console.WriteLine("{0,-35:o} ({1:o})", val, val.ToUniversalTime())
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
日付・時間の新しい順に並べ替えるには、次の例のように並べ替え順序を通常と逆の順序に定義したメソッドを用意してからソートします。 逆順(降順)でのソートについては[[programming/netfx/sorting/0_basictypes#SortDescending]]も参照してください。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+

          
+
class Sample {
+
  // DateTimeを通常と逆の順に並べ替えるためのメソッド
+
  static int CompareDateTimeReverseOrder(DateTime x, DateTime y)
+
  {
+
    // 逆順で比較
+
    return DateTime.Compare(y, x);
+
    // 次のようにしても同じ
+
    //return -DateTime.Compare(x, y);
+
    //return y.CompareTo(x);
+
  }
+

          
+
  static void Main()
+
  {
+
    DateTime[] dateTimeArray = new DateTime[] {
+
      new DateTime(2000, 1, 1,  0, 0, 0),
+
      new DateTime(2000, 1, 1, 12, 0, 0),
+
      new DateTime(2000, 1, 2,  0, 0, 0),
+
      new DateTime(2000, 2, 1,  0, 0, 0),
+
      new DateTime(2001, 1, 1,  0, 0, 0),
+
    };
+

          
+
    // デフォルトの順にソート
+
    Array.Sort(dateTimeArray);
+

          
+
    Console.WriteLine("default order");
+
    foreach (DateTime val in dateTimeArray) {
+
      Console.WriteLine("{0:f}", val);
+
    }
+

          
+
    // 逆順にソート
+
    Array.Sort(dateTimeArray, CompareDateTimeReverseOrder);
+

          
+
    Console.WriteLine("reverse order");
+
    foreach (DateTime val in dateTimeArray) {
+
      Console.WriteLine("{0:f}", val);
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+

          
+
Class Sample
+
  ' DateTimeを通常と逆の順に並べ替えるためのメソッド
+
  Shared Function CompareDateTimeReverseOrder(ByVal x As DateTime, ByVal y As DateTime) As Integer
+
    ' 逆順で比較
+
    Return DateTime.Compare(y, x)
+
    ' 次のようにしても同じ
+
    'Return -DateTime.Compare(x, y)
+
    'Return y.CompareTo(x)
+
  End Function
+

          
+
  Shared Sub Main()
+
    Dim dateTimeArray As DateTime() = New DateTime() { _
+
      New DateTime(2000, 1, 1,  0, 0, 0), _
+
      New DateTime(2000, 1, 1, 12, 0, 0), _
+
      New DateTime(2000, 1, 2,  0, 0, 0), _
+
      New DateTime(2000, 2, 1,  0, 0, 0), _
+
      New DateTime(2001, 1, 1,  0, 0, 0) _
+
    }
+

          
+
    ' デフォルトの順にソート
+
    Array.Sort(dateTimeArray)
+

          
+
    Console.WriteLine("default order")
+
    For Each val As DateTime In dateTimeArray
+
      Console.WriteLine("{0:f}", val)
+
    Next
+

          
+
    ' 逆順にソート
+
    Array.Sort(dateTimeArray, AddressOf CompareDateTimeReverseOrder)
+

          
+
    Console.WriteLine("reverse order")
+
    For Each val As DateTime In dateTimeArray
+
      Console.WriteLine("{0:f}", val)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
default order
+
2000年1月1日 0:00
+
2000年1月1日 12:00
+
2000年1月2日 0:00
+
2000年2月1日 0:00
+
2001年1月1日 0:00
+
reverse order
+
2001年1月1日 0:00
+
2000年2月1日 0:00
+
2000年1月2日 0:00
+
2000年1月1日 12:00
+
2000年1月1日 0:00
+
}}
+

          
+

          
+

          
+
*列挙体 [#DefaultSortOrder_Enum]
+
列挙体は、整数型に準じた並べ替えが行われ、各メンバに与えられている値の大きさに従って小さい順に並べ替えられます。
+

          
+
#prompt(実行結果){{
+
MinusTwo (-2)
+
MinusOne (-1)
+
Zero     (0)
+
One      (1)
+
Two      (2)
+
}}
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+

          
+
enum Number {
+
  MinusTwo = -2,
+
  MinusOne = -1,
+
  Zero = 0,
+
  One = 1,
+
  Two = 2,
+
}
+

          
+
class Sample {
+
  static void Main()
+
  {
+
    Number[] arr = new Number[] {
+
      Number.Zero, Number.One, Number.MinusOne, Number.Two, Number.MinusTwo,
+
    };
+

          
+
    Array.Sort(arr);
+

          
+
    foreach (Number val in arr) {
+
      Console.WriteLine("{0,-8:G} ({0:D})", val);
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+

          
+
Enum Number
+
  MinusTwo = -2
+
  MinusOne = -1
+
  Zero = 0
+
  One = 1
+
  Two = 2
+
End Enum
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim arr As Number() = New Number() { _
+
      Number.Zero, Number.One, Number.MinusOne, Number.Two, Number.MinusTwo _
+
    }
+

          
+
    Array.Sort(arr)
+

          
+
    For Each val As Number In arr
+
      Console.WriteLine("{0,-8:G} ({0:D})", val)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
列挙体をメンバ名の順(値に割り当てられている名前の順)に並べるには、次のように並べ替え順序を定義する必要があります。 ただ、次の例にあるように、列挙体ではメンバ名で定義されていない値も設定できるため、そういった値をどう取り扱うかについての考慮も必要となってきます。
+

          
+
#tabpage(C#)
+
#code(cs){{
+
using System;
+

          
+
enum Number {
+
  MinusTwo = -2,
+
  MinusOne = -1,
+
  Zero = 0,
+
  One = 1,
+
  Two = 2,
+
}
+

          
+
class Sample {
+
  // 列挙体の値を比較するメソッド
+
  static int CompareNumber(Number x, Number y)
+
  {
+
    // 列挙体の値を文字列(メンバ名)に変換
+
    string xx = x.ToString("G");
+
    string yy = y.ToString("G");
+

          
+
    // 文字列として比較した結果を返す
+
    return string.Compare(xx, yy);
+
  }
+

          
+
  static void Main()
+
  {
+
    Number[] arr = new Number[] {
+
      Number.Zero, Number.One, Number.MinusOne, Number.Two, Number.MinusTwo,
+
      (Number)3, // <- 列挙体のメンバで定義されていない値
+
    };
+

          
+
    Array.Sort(arr, CompareNumber);
+

          
+
    foreach (Number val in arr) {
+
      Console.WriteLine("{0,-8:G} ({0:D})", val);
+
    }
+
  }
+
}
+
}}
+
#tabpage(VB)
+
#code(vb){{
+
Imports System
+

          
+
Enum Number
+
  MinusTwo = -2
+
  MinusOne = -1
+
  Zero = 0
+
  One = 1
+
  Two = 2
+
End Enum
+

          
+
Class Sample
+
  ' 列挙体の値を比較するメソッド
+
  Shared Function CompareNumber(ByVal x As Number, ByVal y As Number) As Integer
+
    ' 列挙体の値を文字列(メンバ名)に変換
+
    Dim xx As String = x.ToString("G")
+
    Dim yy As String = y.ToString("G")
+

          
+
    ' 文字列として比較した結果を返す
+
    Return String.Compare(xx, yy)
+
  End Function
+

          
+
  Shared Sub Main()
+
    Dim arr As Number() = New Number() { _
+
      Number.Zero, Number.One, Number.MinusOne, Number.Two, Number.MinusTwo, _
+
      CType(3, Number) _
+
    }
+

          
+
    Array.Sort(arr, AddressOf CompareNumber)
+

          
+
    For Each val As Number In arr
+
      Console.WriteLine("{0,-8:G} ({0:D})", val)
+
    Next
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
3        (3)
+
MinusOne (-1)
+
MinusTwo (-2)
+
One      (1)
+
Two      (2)
+
Zero     (0)
+
}}
+

          
+
列挙体の書式・文字列化については[[programming/netfx/enum/0_enum]]や[[programming/netfx/string_formatting/0_formatstrings]]を参照してください。
+

          
+

          
+

          
+
#navi(..)
+