C#按特定参数对对象数组排序

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

我对编程比较陌生。我有一个不一定满的对象数组(可能包括空行)。我想通过一个类参数“int moveScore”对它进行排序。 这是我的数组(当前仅包含32个条目)

我尝试了两种分类方法

1 在“Score”类中,我继承了“IComparable”,并使用了“CompareTo”方法,如下所示

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-我现在还不知道如何使用列表(还是个学生):-@user3092553
    list 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);
    }