在VB中按整数降序对整数和字符串列表进行排序

时间:2017-09-21 03:12:10

标签: vb.net sorting

我必须制作这个程序,对游戏的高分进行排序,然后用用户名USING LISTS显示它们从大到小。到目前为止我写道:

Public highscore As New List(Of HighScores)

highscore.Add(New HighScores("Jeremias", 6))
highscore.Add(New HighScores("Tom", 1))
highscore.Add(New HighScores("sdf", 5))
highscore.Add(New HighScores("asfd", 1))

highscore.Sort()
highscore.Reverse()

Console.WriteLine("------High Scores-----")
For Each scores In highscore
     Console.WriteLine(scores)
Next
Console.WriteLine("----------------------")

HighScores类:

Public Class HighScores
    Public name As String
    Public score As Integer

    Public Sub New(ByVal name As String, ByVal score As Integer)
        Me.name = name
        Me.score = score
    End Sub

    Public Overrides Function ToString() As String
        Return String.Format("{0}, {1}", Me.name, Me.score)
    End Function
End Class

通常我会使用.Sort()和.Reverse()来对列表进行排序,但在这种情况下我不认为我能做到这一点。我有什么想法可以重写这个/只是轻松地对列表进行排序吗?

1 个答案:

答案 0 :(得分:3)

您可以指定如何以各种方式对List(Of T)进行排序。最简单的就是这样:

highscore.Sort(Function(x, y) y.score.CompareTo(x.score))

使用Sort的重载,它接受Comparison(Of T)委托,并为该委托使用Lambda表达式。请注意,Lambda参数为xy,并且正文在CompareTo score上调用y。这很关键,因为这是使排序按降序排列的原因,并且无需调用Reverse

请注意,您可以使用命名方法而不是Lambda。这样的方法看起来像这样:

Private Function CompareHighScoresByScoreDescending(x As HighScores, y As HighScores) As Integer
    Return y.score.CompareTo(x.score)
End Function

要排序的代码如下所示:

highscore.Sort(AddressOf CompareHighScoresByScoreDescending)

在比较对象以进行排序时,惯例是使用-1,0和1来表示相对位置。这就是CompareTo的作用,因此这就是我们的比较方法在这里所做的。如果您在CompareTo上调用的对象在概念上较少传递的对象,则结果为-1。 1表示第一个对象大于第二个对象,0表示它们相等。该方法可以像这样重写:

Private Function CompareHighScoresByScoreDescending(x As HighScores, y As HighScores) As Integer
    If y.score < x.score Then
        Return -1
    ElseIf y.score > x.score Then
        Return 1
    Else
        Return 0
    End If
End Function

使用IComparable类型的现有Integer实现显然更为简洁,即CompareTo方法。

顺便说一句,您的代码可以在其他方面使用一些改进。首先,HighScores不是该类的合适名称。它代表一个单一的东西,所以名称不应该是复数,它实际上并不代表自己的高分。更合适的名称是PlayerScore,因为它更准确地描述了它所代表的内容。

其次,您的List变量实际上代表多个对象,即包含多个项目的列表,因此它的名称应该是复数。它实际上也代表高分,因此它应该被命名为highScores

最后,公开公开成员变量几乎是普遍的坏习惯。你应该绝对使用该类中的属性:

作为奖励,如果你使用VS 2015或更高版本,那么你也可以用字符串插值替换String.Format

Public Class PlayerScore

    Public Property Name As String
    Public Property Score As Integer

    Public Sub New(name As String, score As Integer)
        Me.Name = name
        Me.Score = score
    End Sub

    Public Overrides Function ToString() As String
        Return $"{Name}, {Score}"
    End Function

End Class