[英]Multidimensional array column sorting
假设我创建此代码以生成idv-th随机数。 但我排序数组有困难取决于最后一列。
假设个体大小是[idv,width] = [8,6],我想用第6列对所有行进行排序......我想在排序之后取出数组中的4个顶部列表。 我怎样才能将这个案例实现到代码?
public static void population(double[,] individual, int width, int idv, Random rnd)
{
for (int i = 0; i < idv; i++)
{
Console.Write("individual {0} :\t", i+1);
for (int j = 0; j < width; j++)
{
individual[i, j] = Math.Round(rnd.NextDouble() * 10, 2);
Console.Write("{0} ", individual[i, j]);
}
Console.WriteLine("\n");
}
}
谢谢
我建议你使用锯齿状数组 double[][]
而不是2d double[,]
。 Jagged数组只是一个数组数组 ,您可以通过Linq帮助轻松排序,过滤等等:
double[][] individual = new double[][] {
new double[] {81, 82, 83, 84, 85, 86},
new double[] {11, 12, 13, 14, 15, 16},
new double[] {41, 42, 43, 44, 45, 46},
new double[] {31, 32, 33, 34, 35, 36},
new double[] {51, 52, 53, 54, 55, 56},
new double[] {21, 22, 23, 24, 25, 26},
new double[] {61, 62, 63, 64, 65, 66},
new double[] {71, 72, 73, 74, 75, 76},
};
double[][] fragment = individual
.OrderBy(line => line[line.GetUpperBound(0)]) // by last column
.Take(4)
.ToArray();
还有一个Linq来测试结果:
String test = String.Join(Environment.NewLine, fragment
.Select(line => String.Join("\t", line)));
Console.Write(test);
结果是
11 12 13 14 15 16
21 22 23 24 25 26
31 32 33 34 35 36
41 42 43 44 45 46
如果你使用多维数组,使用LINQ没有简单的方法可以使用它们,你需要依赖于旧for
。
static void Main ()
{
// Input array
double[,] u = {
{ 1, 9, 3 },
{ 0, 3, 4 },
{ 3, 4, 5 },
{ 3, 6, 8 },
{ 3, 5, 7 },
};
// Get dimension sizes, specify column to order by
int count = u.GetLength(0), length = u.GetLength(1), orderBy = 2;
// Result array
double[,] v = new double[count, length];
// Construct a list of indices to sort by
var indices = Enumerable.Range(0, count).OrderBy(i => u[i, orderBy]).ToList();
// Copy values from input to output array, based on these indices
for (int i = 0; i < count; i++)
for (int j = 0; j < length; j++)
v[i, j] = u[indices[i], j];
PrintArray(u);
Console.WriteLine();
PrintArray(v);
}
static void PrintArray (double[,] a)
{
for (int i = 0; i < a.GetLength(0); i++) {
for (int j = 0; j < a.GetLength(1); j++)
Console.Write(a[i, j]);
Console.WriteLine();
}
}
如果只需要前4行,可以在ToList()
调用之前添加Take(4)
并调整结果数组创建并适当地将值复制到其中。
多维数组更有效并且使用更少的内存,因此如果您的数组足够大或者您需要更快地使用它们,您可能需要编写更多代码并使用多维数组而不是更容易使用的锯齿状数组。
对于矩形数组[,]
您可以将所需列与索引一起复制到一维数组中,对其进行排序,然后获得前4个索引的行。
static IEnumerable<Tuple<int, double>> GetColumn(int columnIndex, double[,] a)
{
for (int i = a.GetLowerBound(0); i <= a.GetUpperBound(0); i++)
yield return Tuple.Create(i, a[i, columnIndex]);
}
double [,] data = ...;
var column = GetColumn(4, data);
var top4Indices = column.OrderBy(v => v.Second)
.Take(4)
.Select(v => v.First);
foreach (int i in top4Indices)
for (int j = data.GetLowerBound(1); j <= data.GetUpperBound(1); j++)
data[i, j]...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.