配列が可変長であることを示したように( SQL Server階層IDであるため)、カスタムIComparer<byte[]>
実装を作成する必要があります。
ロジックは単純です。
n
各アレイの最初のバイトをバイトごとに比較します。ここn
で、は2つのアレイのうち小さい方のバイト数です。いずれかのバイト間で差異が検出された場合は、異なるバイトの比較結果を返します。
- 最初の
n
バイトが等しい場合は、2つの配列の長さの比較を返します。
このように、次のようなデータセットが与えられます。
00 01 02
00 01
01
並べ替えると、次のような結果が得られます。
00 01
00 01 02
01
そうは言っても、これはあなたのIComparer<byte[]>
実装がどのように見えるかです:
// I could be wrong in that this is called natural order.
class NaturalOrderByteArrayComparer : IComparer<byte[]>
{
public int Compare(byte[] x, byte[] y)
{
// Shortcuts: If both are null, they are the same.
if (x == null && y == null) return 0;
// If one is null and the other isn't, then the
// one that is null is "lesser".
if (x == null && y != null) return -1;
if (x != null && y == null) return 1;
// Both arrays are non-null. Find the shorter
// of the two lengths.
int bytesToCompare = Math.Min(x.Length, y.Length);
// Compare the bytes.
for (int index = 0; index < bytesToCompare; ++index)
{
// The x and y bytes.
byte xByte = x[index];
byte yByte = y[index];
// Compare result.
int compareResult = Comparer<byte>.Default.Compare(xByte, yByte);
// If not the same, then return the result of the
// comparison of the bytes, as they were the same
// up until now.
if (compareResult != 0) return compareResult;
// They are the same, continue.
}
// The first n bytes are the same. Compare lengths.
// If the lengths are the same, the arrays
// are the same.
if (x.Length == y.Length) return 0;
// Compare lengths.
return x.Length < y.Length ? -1 : 1;
}
}
余談ですが、バイト配列が同じ長さであることが保証されている場合は、別の方法として、次のように、order by句を動的に作成し、最初の要素、次に2番目の要素などで並べ替えることができます。
static IEnumerable<foo> OrderBySortField(this IEnumerable<foo> items,
int sortLength)
{
// Validate parameters.
if (items == null) throw new ArgumentNullException("items");
if (sortLength < 0) throw
new ArgumentOutOfRangeException("sortLength", sortLength,
"The sortLength parameter must be a non-negative value.");
// Shortcut, if sortLength is zero, return the sequence, as-is.
if (sortLength == 0) return items;
// The ordered enumerable.
IOrderedEnumerable<foo> ordered = items.OrderBy(i => i.sort[0]);
// Cycle from the second index on.
for (int index = 1; index < sortLength; index++)
{
// Copy the index.
int indexCopy = index;
// Sort by the next item in the array.
ordered = ordered.ThenBy(i => i.sort[indexCopy]);
}
// Return the ordered enumerable.
return ordered;
}
そして、あなたはそれをそのように単に呼ぶことができます:
// You have to supply the length of the array you're sorting on.
List<foo> sortedFoo = FooSource().
OrderBySortField(sortLength).ToList();