我正在尝试将此多维数组排列为升序或降序。但是,我需要第1列和第2列之间的关系仍然在一起(意味着我需要例如数组[0,1]和数组[0,2]的数据在一起或以某种方式相关。这是我现在的代码。
int[,] time = new int[5,2]{{0,4},{1,5},{5,10},{3,4},{0,2}};
var sorted = from x in Enumerable.Range(0, time.GetLength(0))
from y in Enumerable.Range(0, time.GetLength(1))
select new{
X = x,
Y = y,
Value = time[x,y]
}into point
orderby point.Value descending
select point;
这有效,但它将我的所有数据分开。有没有办法在保持第1列和第2列的关系的同时对它们进行排序?
答案 0 :(得分:5)
我很好奇为什么你需要一个多维数组。很明显,您将数据视为"行的一维集合,"而不是"细胞的二维集合。"
为什么不简单地创建一个List(T),其中T是某种Tuple或自定义结构?
从表面上看,似乎你正试图在指甲上使用螺丝刀;确保你为工作挑选合适的工具;)
答案 1 :(得分:2)
听起来您希望将数据存储在多维数组中,但将数组中的每一行保留为单独的原子单元。另外,每个“点”的比较是X,然后是Y.
int[,] time = new int[5, 2] { { 0, 4 }, { 1, 5 }, { 5, 10 }, { 3, 4 }, { 0, 2 } };
var sorted = from x in Enumerable.Range(0, time.GetLength(0))
select new Point()
{
X = time[x,0],
Y = time[x,1]
} into point
orderby point.X ascending , point.Y ascending
select point;
int[,] sortedTime = new int[5,2];
int index = 0;
foreach (var testPoint in sorted)
{
Point aPoint = (Point) testPoint;
sortedTime.SetValue(aPoint.X, index, 0);
sortedTime.SetValue(aPoint.Y, index, 1);
index++;
}
答案 2 :(得分:0)
看起来你可能只是在过度思考。例如,如果要将点保持在一起并按第一列排序,只需省略第二个Enumerable.Range
并手动分配值:
int[,] time = new int[5,2]{{0,4},{1,5},{5,10},{3,4},{0,2}};
var sorted = from x in Enumerable.Range(0, time.GetLength(0))
select new{
X = time[x,0],
Y = time[x,1]
}into point
orderby point.X descending
select point;
正如@Haxx指出的那样,如果第二个值的顺序也很重要,只需将, point.Y descending
添加到orderby
子句中。
答案 3 :(得分:0)
我还认为应该将此视为行的集合,因为您希望行始终保持在一起。
.NET具有DataTable
类型。例如。
int[,] time = new int[5, 2] { { 0, 4 }, { 1, 5 }, { 15, 10 }, { 3, 4 }, { 0, 2 } };
DataTable dt = new DataTable();
dt.Columns.Add("x", System.Type.GetType("System.Int32"));
dt.Columns.Add("y", System.Type.GetType("System.Int32"));
for (int i = 0; i < time.Length / 2; i++)
{
DataRow dr = dt.NewRow();
dr[0] = time[i, 0];
dr[1] = time[i, 1];
dt.Rows.Add(dr);
}
dt.DefaultView.Sort = "x" + " " + "ASC";
dt = dt.DefaultView.ToTable();
请注意,我需要输入表格列。否则你会按字母顺序排序。我将您的一个数字更改为15,以证明排序适用于整数(15> 3,但按字母顺序“15”<“3”)。如果您真的希望它作为2D阵列返回,请参阅第一个答案。
答案 4 :(得分:0)
最快的方法是实施一些排序算法,如Quicksort
,并将其修改为仅使用Compare(i, j)
和Swap(i, j)
函数。
然后,您可以为多维数组实现这些函数并对其进行排序。
这是一个有效的实施方案:
public static void Main() {
int[,] time = new int[5, 2] { { 0, 4 }, { 1, 5 }, { 5, 10 }, { 3, 4 }, { 0, 2 } };
DoSort(time);
}
public static void DoSort(int[,] data) {
Func<int, int, int> comparer = (i, j) => {
int s1 = Math.Sign(data[i, 0] - data[j, 0]);
if (s1 != 0) {
return s1;
}
int s2 = Math.Sign(data[i, 1] - data[j, 1]);
return s2;
};
Action<int, int> swapper = (i, j) => {
var tmp0 = data[i, 0];
var tmp1 = data[i, 1];
data[i, 0] = data[j, 0];
data[i, 1] = data[j, 1];
data[j, 0] = tmp0;
data[j, 1] = tmp1;
};
int length = data.GetLength(0);
Quicksort(comparer, swapper, 0, length - 1);
}
public static void Quicksort(Func<int, int, int> comparer, Action<int, int> swapper, int left, int right) {
int i = left, j = right;
int pivotIdx = (left + right) / 2;
while (i <= j) {
while (comparer(i, pivotIdx) < 0) {
i++;
}
while (comparer(j, pivotIdx) > 0) {
j--;
}
if (i <= j) {
swapper(i, j);
i++;
j--;
}
}
// Recursive calls
if (left < j) {
Quicksort(comparer, swapper, left, j);
}
if (i < right) {
Quicksort(comparer, swapper, i, right);
}
}
}
此代码对数组进行就地排序,因此您不需要额外的内存,最终得到一个有序的多维数组。
答案 5 :(得分:0)
假设:
1。您希望保持项目配对,例如想要{0,4}作为一对,{1,5}作为另一对。
2。升序的预期结果是:{{0,2},{0,4},{1,5},{3,4},{5,10}}。
正如BTownTKD所建议的那样,强烈建议使用一些类/结构来表示你的对,而不是使用多维数组。您可以使用以下任一列表/数组:
Tuple<int, int>
KeyValuePair<int, int>
这不仅可以帮助您排序,还可以轻松地进行进一步的操作。仅当您有非常特殊的需要时才使用多维数组。
以下是使用Tuple的示例代码:
List<Tuple<int, int>> time = new List<Tuple<int, int>>(){
new Tuple<int, int>(0,4),
new Tuple<int, int>(1,5),
new Tuple<int, int>(5,10),
new Tuple<int, int>(3,4),
new Tuple<int, int>(0,2)
};
//Sort Ascending
time.Sort((first, second) =>
{
var item1Compare = first.Item1.CompareTo(second.Item1);
return item1Compare == 0 ? first.Item2.CompareTo(second.Item2) : item1Compare;
});
//Sort Descending
/*time.Sort((first, second) =>
{
var item1Compare = second.Item1.CompareTo(first.Item1);
return item1Compare == 0 ? second.Item2.CompareTo(first.Item2) : item1Compare;
});*/