我认为被接受的答案非常好。可以像那个答案中所示一样使用匿名类型,或者声明一个命名类型来保存数据并进行排序。
更好的做法是始终声明一个命名类型来保存数据。并行数组通常不是一个好主意。有一些利用性能或互操作性的小众场景需要它们,但除此之外应该避免使用它们。
话虽如此,为了完整起见,我认为也指出数组可以通过“代理”进行排序会很有用。即创建一个新数组,其中只包含原始数组的索引,并对该数组进行排序。一旦索引数组已经排序,您就可以使用该数组直接访问原始数据,或者使用该数组将原始数据复制到新的排序数组中。
例如:
static void Main(string[] args)
{
int[] values = { 10, 20, 20, 10, 30 };
int[] keys = { 1, 2, 3, 4, 5 };
int[] indexes = Enumerable.Range(0, values.Length).ToArray();
Array.Sort(indexes, (i1, i2) => Compare(i1, i2, values, keys));
for (int i = 0; i < values.Length; i++)
{
Console.WriteLine("{0}: {1}", values[indexes[i]], keys[indexes[i]]);
}
Console.WriteLine();
values = OrderArray(values, indexes);
keys = OrderArray(keys, indexes);
for (int i = 0; i < values.Length; i++)
{
Console.WriteLine("{0}: {1}", values[i], keys[i]);
}
}
private static int Compare(int i1, int i2, int[] values, int[] keys)
{
int result = values[i1].CompareTo(values[i2]);
if (result == 0)
{
result = keys[i1].CompareTo(keys[i2]);
}
return result;
}
private static int[] OrderArray(int[] values, int[] indexes)
{
int[] result = new int[values.Length];
for (int i = 0; i < values.Length; i++)
{
result[i] = values[indexes[i]];
}
return result;
}