在VB.NET中对多维数组进行排序

5

I have a 2X50 array like this-

R-125212,11
C-254645,25
R-456598,96
M-456878,35
O-980857,89
And so on...

现在我想按第二列的值对这个数组进行排序。因此,输出应该如下所示-

R-125212,11
C-254645,25
M-456878,35
O-980857,89
R-456598,96
And so on...

如何轻松使用VB.NET实现这一点?如果有其他更好的方法可以获得类似的结果而不需要使用数组,那也会帮助我。

如果将数据类型更改为整数可以轻松排序,那么我可以这样做。 - nsssayom
类型不重要。它是唯一标识符吗?如果是,那么创建一个类,你可以根据属性进行排序。 - A Friend
据我所见,您有 Char - IntegerInteger 数据,您想按第二列进行排序。 - 3vts
你能回答被问到的问题吗?至少在我开始打字之前,没有人问过数据类型是什么。问题是这些数据实际上代表什么。原因是你的数据几乎肯定可以用一个具有三个属性的类型的一维数组或对象集合更好地表示。排序只需要调用一个方法即可。 - jmcilhinney
@jmcilhinney 第一列代表学生ID,第二列是他们的分数。 - nsssayom
显示剩余9条评论
3个回答

6

有很多可能的解决方案可供选择,但在我的经验中,最好的方法是使用一个System.Data.DataTable

Dim dtb As New System.Data.DataTable
dtb.Columns.Add("Column1")
dtb.Columns.Add("Column2", GetType(Integer))
dtb.Rows.Add("Z-123456", 2)
dtb.Rows.Add("R-125212", 11)
dtb.Rows.Add("C-254645", 25)
dtb.Rows.Add("R-456598", 96)
dtb.Rows.Add("M-456878", 35)
dtb.Rows.Add("O-980857", 89)
Dim dvw As DataView = dtb.DefaultView
dvw.Sort = "Column2 ASC"
Dim dtbSorted As DataTable = dvw.ToTable()
DataGridView1.DataSource = dtbSorted

除非您直接从数据库中读取数据,否则最好不要使用 DataTable。如果您可以以其他方式填充 DataTable,那么您可以填充专用类型的实例集合。 - jmcilhinney
@jmcilhinney - 是的,可以创建自定义类并实现IComparable等接口,但DataTable更快、更容易编码。 - SSS
为什么需要实现 IComparable 接口?排序可以通过 StringInteger 属性完成,这两个属性已经实现了 IComparable 接口。如果不想使用自定义类,甚至不需要,因为有 Tuple 类型。创建一个对 List(Of Tuple(Of String, Integer)) 进行排序的代码将比使用 DataTable 更简单。 - jmcilhinney
1
顺便提一下,你对包含数字的文本列进行排序的示例只有在每个值具有相同长度时才能正常工作。就像你所演示的那样,"10" 会在排序中排在 "9" 前面。 - jmcilhinney
最终,我猜解决这个问题有很多方法。你对整数排序的看法是正确的 - DataTable 支持大多数数据类型作为其列(即使是自定义类型/类,如果我没记错的话),我会更新我的答案。 - SSS

6

我建议使用List(Of Tuple)代替数组,它更具有动态性。请查看以下代码:

Sub SortList()
    'Declare the List Of Tuple with a Tuple of Char, Integer, Integer
    Dim lstToSort As New List(Of Tuple(Of Char, Integer, Integer))
    'Example to Add items
    lstToSort.Add(Tuple.Create("R"c, 250645, 11))
    lstToSort.Add(Tuple.Create("C"c, 125212, 25))
    'Sort is just 1 line
    lstToSort = lstToSort.OrderBy(Function(i) i.Item2).ToList
    'Loop through the elements to print them
    For Each tpl As Tuple(Of Char, Integer, Integer) In lstToSort
        Console.WriteLine(tpl.Item1 & "-" & tpl.Item2 & "," & tpl.Item3)
    Next
End Sub

编辑:根据您对问题的编辑,以下是修复后的代码:

Sub SortList()
    'Declare the List Of Tuple with a tuple of String, Integer
    Dim lstToSort As New List(Of Tuple(Of String, Integer))
    'Example to add items
    lstToSort.Add(Tuple.Create("R-250645", 11))
    lstToSort.Add(Tuple.Create("C-125212", 25))
    'Sort is just 1 line
    lstToSort = lstToSort.OrderBy(Function(i) i.Item2).ToList
    'Loop through the elements to print them
    For Each tpl As Tuple(Of String, Integer) In lstToSort
        Console.WriteLine(tpl.Item1 & "," & tpl.Item2)
    Next
End Sub

请尝试并让我知道您的评论。


我相信这会起作用。但是我会在我的解决方案中使用先前的答案,因为它为我提供了一些次要的好处。 - nsssayom
2
这对我之前遇到的类似问题非常有效! - JerryT
@JerryT 很高兴能帮到你。 - 3vts
1
不知道元组,谢谢! - MrCalvin

0

代码:

Public Function Sort2DimArray(SA As Array, order As Boolean, sc0 As Integer, Optional sc1 As Integer = -1, Optional sc2 As Integer = -1) As Array

    Dim cols As Integer = SA.GetLength(1) - 1
    Dim rows As Integer = SA.GetLength(0) - 1
    Dim na(rows, cols) As String
    Dim a(rows) As String
    Dim b(rows) As Integer
    Dim c As Integer = 1
    If sc1 > -1 Then c = c + 1
    If sc2 > -1 Then c = c + 1

    For x = 0 To rows
        If c = 1 Then a(x) = SA(x, sc0)
        If c = 2 Then a(x) = SA(x, sc0) & SA(x, sc1)
        If c = 3 Then a(x) = SA(x, sc0) & SA(x, sc1) & SA(x, sc2)
        b(x) = x
    Next
    Array.Sort(a, b)
    If order = False Then
        For x = 0 To rows
            For y = 0 To cols
                na(x, y) = SA(b(x), y)
            Next
        Next
    Else
        For x = 0 To rows
            For y = 0 To cols
                na(rows - x, y) = SA(b(x), y)
            Next
        Next
    End If
    Sort2DimArray = na
End Function

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接