C#按特定参数对对象数组排序
我对编程比较陌生。我有一个不一定满的对象数组(可能包括空行)。我想通过一个类参数“int moveScore”对它进行排序。 这是我的数组(当前仅包含32个条目) 我尝试了两种分类方法 1 在“Score”类中,我继承了“IComparable”,并使用了“CompareTo”方法,如下所示C#按特定参数对对象数组排序,c#,arrays,sorting,C#,Arrays,Sorting,我对编程比较陌生。我有一个不一定满的对象数组(可能包括空行)。我想通过一个类参数“int moveScore”对它进行排序。 这是我的数组(当前仅包含32个条目) 我尝试了两种分类方法 1 在“Score”类中,我继承了“IComparable”,并使用了“CompareTo”方法,如下所示 public int CompareTo(object obj) { Score x = (Score)obj; if (this.move
public int CompareTo(object obj)
{
Score x = (Score)obj;
if (this.moveScore < x.moveScore)
return -1;
if (this.moveScore > x.moveScore)
return 1;
return 0;
}
问题是它确实正确排序,但排序在数组的末尾。这意味着行0-966为“null”,967-999排序正确(967为最高“int”,999为最低)。
有没有办法解决这个问题
2
我也试过这个
Array.Sort(firstPlyScore, delegate
(Score x, Score y) { return x.moveScore.CompareTo(y.moveScore); });
这里的问题是当它到达一个“null”行时崩溃了
非常感谢您的帮助 您可以使用Linq to Entities进行排序,然后将其转换回数组。它将重新调整数组的大小,使其达到所需的正确长度,而不会出现空值问题
var list = firstPlyScore.OrderByDescending(x => x.MoveScore).ToList();
//here how you can get always 1000 array length as you asked
for (int i = list.Count-1; i < 1000; i++)
{
list.Add(null);
}
firstPlyScore = list.ToArray();
}
var list=firstPlyScore.OrderByDescending(x=>x.MoveScore.ToList();
//这里介绍了如何按照您的要求始终获得1000个数组长度
对于(int i=list.Count-1;i<1000;i++)
{
list.Add(空);
}
firstPlyScore=list.ToArray();
}
在比较方法的开头
if(obj == null) return 0;
问题是,它确实正确排序,但排序在最后
数组。这意味着第0-966行为“空”,第967-999行排序正确
(967的“int”值最高,999的“int”值最低)。有什么办法可以解决吗
这个
如果您需要一些大小可以改变的东西,您需要的是列表
,而不是使用数组。
数组应用于不变的列表(如棋盘)
该列表还提供了一个名为的方法
正如其他人所提到的,您也可以使用LINQ来实现所需的功能。默认比较行为是将
null
值排序在非null
值之前。如果您希望覆盖此行为,则可以像第二个示例中那样进行自定义的比较
delegate (Score x, Score y) {
if (x == null)
return y == null ? 0 : 1;
if (y == null)
return -1;
return x.moveScore.CompareTo(y.moveScore);
}
这将使null
项保留在数组的末尾
要按降序排序,只需交换最后一行中的x
和y
引用。即使大多数项为空,您真的需要在列表中保留1000项吗?
我建议你检查一下它背后的逻辑,看看你是否能阻止它,因为这会白白占用很多空间
否则,有两种可能性:
在比较函数中检查Obj==null。但如果比较项为空,则仍可能失败
为您的分数创建一个自定义类,并使其具有Icomparable(查看有关如何对数组排序的几个示例)
你想省略空行吗?你考虑过使用列表而不是数组吗?这样你可以很容易地避免那些空条目。对mfanto-我不想省略空行。对Jon Skeet-我现在还不知道如何使用列表(还是个学生):-@user3092553list scoreList=new list()
,它将创建一个“开放式”的Score
对象集合,您可以将Add()
添加到其中。请看,因为有些条目为空x。MoveScore将失败感谢您的回复,但我仍然得到一个“NullReferenceException”。添加where
并将Order
更改为OrderByDescending
使其成为我的答案:)谢谢!它是有效的,但是。。。1) 我需要数组按降序排序。2) 我确实需要数组为1000,以便将来的迭代+1,因为这里的数组是poo,这应该可以工作(并且不会“丢失”所有null
条目)。谢谢!这实际上只适用于按升序排序的情况。如何让它降序排序?@user3092553,返回y.moveScore.CompareTo(x.moveScore)代码>应该这样做,谢谢!它是有效的,但是。。。我需要阵列为1000,以便将来迭代。可以保持在1000吗?@user3092553只需在OrderByDescending之后添加.Concat(firstPlyScore.Where(x=>x==null))
。最后的linq是:firstPlyScore=firstPlyScore.Where(x=>x!=null).OrderByDescending(x=>x.moveScore).Concat(firstPlyScore.Where(x=>x==null)).ToArray()代码>即使这确实有效,但代码非常冗长,很难理解。上面的自定义比较选项是一种更好的方法。@lightning很难理解
?也许是给你的。也许不是所有的,但它展示了另一种使用Linq的方法。因此,除非它是错误的,否则它可以被认为是一个答案。
if(obj == null) return 0;
firstPlyScore = firstPlyScore
.Where(x => x != null)
.OrderByDescending(x => x.moveScore)
.ToArray();
delegate (Score x, Score y) {
if (x == null)
return y == null ? 0 : 1;
if (y == null)
return -1;
return x.moveScore.CompareTo(y.moveScore);
}