ネタ元 → 複数キーによるソートについて
まず年齢の昇順に並べ、同年齢なら名前の昇順で... なんてケースですなたぶん。
よくあるケースです。
だいぶ手慣れてきたC#でやってみた。
using System;
namespace MultiKey_cs {
/*
* ぶっちゃけキモはこいつだけ。
*/
class MultiKeyComp<T> {
Comparison<T>[] comps;
public MultiKeyComp(params Comparison<T>[] c) {
comps = c;
}
private int compare(T x, T y) {
int result = 0;
foreach ( Comparison<T> c in comps ) {
if ( (result = c(x, y)) != 0 ) break;
}
return result;
}
// Comparison<T> への暗黙の変換
public static implicit operator Comparison<T>(MultiKeyComp<T> arg) {
return arg.compare;
}
}
public struct データ {
public string key1;
public string key2;
public string key3;
}
public class Program {
public static void Main() {
int N = 10;
データ[] data = new データ[N];
Random r = new Random();
for ( int i = 0; i < N; ++i ) {
データ datum = new データ();
datum.key1 = r.Next(10).ToString();
datum.key2 = r.Next(10).ToString();
datum.key3 = r.Next(10).ToString();
data[i] = datum;
}
Console.WriteLine("ソート前");
Array.ForEach(data,
x => Console.WriteLine("{0} {1} {2}", x.key1, x.key2, x.key3));
Console.WriteLine();
Comparison<データ> c =
new MultiKeyComp<データ>(
(x,y) => x.key1.CompareTo(y.key1), // key1:昇順
(x,y) => 0, // key2:don't care
(x,y) => y.key3.CompareTo(x.key3) // key3:降順
);
Array.Sort(data, c);
Console.WriteLine("ソート後");
Array.ForEach(data,
x => Console.WriteLine("{0} {1} {2}", x.key1, x.key2, x.key3));
Console.WriteLine();
}
}
}
lambdaらぶ♪
未だLINQ脳が未発達なもので ^^;