Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 创建和排序数组/arraylist/list_.net_Arrays_Vb.net_List_Sorting - Fatal编程技术网

.net 创建和排序数组/arraylist/list

.net 创建和排序数组/arraylist/list,.net,arrays,vb.net,list,sorting,.net,Arrays,Vb.net,List,Sorting,目前,我有一个(字符串)列表,其中包含类似以下内容的数据: "207.5,1" "373,2" "278.5,3" "134,4" "277,5" "674,7" "58.5,9" 对于此列表,我应用两个命令“list.Sort”然后“list.Reverse”,这两个命令都完全按照预期执行,我的列表包含: "674,7" "58.5,9" "373,2" "278.5,3" "277,5" "207.5,1" "134,4" 正如您所看到的,无论出于何种目的,这都非常有效,但是目光敏锐的人

目前,我有一个(字符串)列表,其中包含类似以下内容的数据:

"207.5,1"
"373,2"
"278.5,3"
"134,4"
"277,5"
"674,7"
"58.5,9"
对于此列表,我应用两个命令“list.Sort”然后“list.Reverse”,这两个命令都完全按照预期执行,我的列表包含:

"674,7"
"58.5,9"
"373,2"
"278.5,3"
"277,5"
"207.5,1"
"134,4"
正如您所看到的,无论出于何种目的,这都非常有效,但是目光敏锐的人会注意到条目“58.5,9”不合适,应该位于列表的底部

我很感激我在这里整理字符串,所以我肯定会失败。我需要发现的是,如何将每行字符串的内容复制到另一个可排序的容器中,该容器将我的数字和“索引”存储为整数和/或单数?理想情况下,我最终会得到一个数组或类似这样的任何数据:

674.0,7
373.0,2
278.5,3
277.0,5
207.5,1
134.0,4
58.5,9

我已经尝试了尽可能多的迭代(这是一个相当新的迭代,所以可能错过了非常明显的!)。如果可以的话,请帮忙!谢谢。

您可以使用LINQ做您想做的事情。如果只希望字符串按正确顺序排序,可以使用:

Dim input = {
    "207.5,1",
    "373,2",
    "278.5,3",
    "134,4",
    "277,5",
    "674,7",
    "58.5,9"
}

Dim sorted =
    From item In input
    Let n = CDec(item.Split(","c)(0))
    Order By n Descending
    Select item
Dim sorted2 =
    From item In input
    Let parts = item.Split(","c)
    Select result = New With { .n = CDec(parts(0)), .idx = CInt(parts(1)) }
    Order By result.n Descending
这只是将第一个数字转换为十进制以用于排序。如果要提取具有两个数字的对象,可以使用:

Dim input = {
    "207.5,1",
    "373,2",
    "278.5,3",
    "134,4",
    "277,5",
    "674,7",
    "58.5,9"
}

Dim sorted =
    From item In input
    Let n = CDec(item.Split(","c)(0))
    Order By n Descending
    Select item
Dim sorted2 =
    From item In input
    Let parts = item.Split(","c)
    Select result = New With { .n = CDec(parts(0)), .idx = CInt(parts(1)) }
    Order By result.n Descending

这为您提供了一个具有
n
idx
属性的IEnumerable匿名类型-如果您不需要匿名类型(例如,您需要从函数返回),您可以创建一个类并创建该类的实例。

您可以使用LINQ来执行您想要的操作。如果只希望字符串按正确顺序排序,可以使用:

Dim input = {
    "207.5,1",
    "373,2",
    "278.5,3",
    "134,4",
    "277,5",
    "674,7",
    "58.5,9"
}

Dim sorted =
    From item In input
    Let n = CDec(item.Split(","c)(0))
    Order By n Descending
    Select item
Dim sorted2 =
    From item In input
    Let parts = item.Split(","c)
    Select result = New With { .n = CDec(parts(0)), .idx = CInt(parts(1)) }
    Order By result.n Descending
这只是将第一个数字转换为十进制以用于排序。如果要提取具有两个数字的对象,可以使用:

Dim input = {
    "207.5,1",
    "373,2",
    "278.5,3",
    "134,4",
    "277,5",
    "674,7",
    "58.5,9"
}

Dim sorted =
    From item In input
    Let n = CDec(item.Split(","c)(0))
    Order By n Descending
    Select item
Dim sorted2 =
    From item In input
    Let parts = item.Split(","c)
    Select result = New With { .n = CDec(parts(0)), .idx = CInt(parts(1)) }
    Order By result.n Descending

这为您提供了一个具有
n
idx
属性的IEnumerable匿名类型-如果不需要匿名类型,您可以创建一个类并创建该类的实例(例如,您需要从函数返回它).

如果要多次使用该数据,则有一个表示该数据的类是有意义的。通过这种方式,您可以为这些部分指定有意义的名称,有一种简单的方法来创建新项,轻松地操作数据,并有自己的方法将其转换为字符串

它可能看起来像是一堆烦琐的代码,但您只需编写一次,当您想要使用数据时,您的生活就会简单得多:

Option Infer On
Option Strict On

Module Module1

    Public Class Datum
        Property Number As Decimal
        Property Index As Integer

        Sub New()
            ' default constructor
        End Sub

        Sub New(NumberIndex As String)
            Dim parts = NumberIndex.Split(","c)
            ' a simple parameter check
            If parts.Length <> 2 Then
                Throw New ArgumentException("No comma found in " & NameOf(NumberIndex))
            End If

            Number = CDec(parts(0))
            Index = CInt(parts(1))

        End Sub

        Public Overrides Function ToString() As String
            Return $"{Number},{Index}"

        End Function

    End Class

    Sub Main()
        Dim myList As New List(Of String) From {"207.5,1", "373,2", "278.5,3", "134,4", "277,5", "674,7", "58.5,9"}
        Dim myData = (myList.Select(Function(d) New Datum(d))).ToList()

        Dim dataDescending = myData.OrderByDescending(Function(d) d.Number).ToList()

        Console.WriteLine(String.Join(vbCrLf, dataDescending))

        Console.ReadLine()

    End Sub

End Module

如果要多次使用该数据,那么有一个表示该数据的类是有意义的。通过这种方式,您可以为这些部分指定有意义的名称,有一种简单的方法来创建新项,轻松地操作数据,并有自己的方法将其转换为字符串

它可能看起来像是一堆烦琐的代码,但您只需编写一次,当您想要使用数据时,您的生活就会简单得多:

Option Infer On
Option Strict On

Module Module1

    Public Class Datum
        Property Number As Decimal
        Property Index As Integer

        Sub New()
            ' default constructor
        End Sub

        Sub New(NumberIndex As String)
            Dim parts = NumberIndex.Split(","c)
            ' a simple parameter check
            If parts.Length <> 2 Then
                Throw New ArgumentException("No comma found in " & NameOf(NumberIndex))
            End If

            Number = CDec(parts(0))
            Index = CInt(parts(1))

        End Sub

        Public Overrides Function ToString() As String
            Return $"{Number},{Index}"

        End Function

    End Class

    Sub Main()
        Dim myList As New List(Of String) From {"207.5,1", "373,2", "278.5,3", "134,4", "277,5", "674,7", "58.5,9"}
        Dim myData = (myList.Select(Function(d) New Datum(d))).ToList()

        Dim dataDescending = myData.OrderByDescending(Function(d) d.Number).ToList()

        Console.WriteLine(String.Join(vbCrLf, dataDescending))

        Console.ReadLine()

    End Sub

End Module

最简单的方法,至少就代码行而言,是使用允许
比较器的
排序
重载。但是,如果您经常使用这些值的数值,则应该考虑数据的类或结构。

我可以将每行字符串的内容复制到另一个可排序的容器中吗

问题不在于容器,而在于数据。数字字符串不按数值排序

Private Function ThingsCompare(x As String, y As String) As Int32
    Dim xVal As Double = Convert.ToDouble(x.Split(","c)(0))
    Dim yVal As Double = Convert.ToDouble(y.Split(","c)(0))

    If xVal < yVal Then Return -1
    If yVal < xVal Then Return 1

    ' equal, so compare segment 2
    Dim xVal2 As Double = Convert.ToDouble(x.Split(","c)(1))
    Dim yVal2 As Double = Convert.ToDouble(y.Split(","c)(1))

    If xVal2 < yVal2 Then Return -1
    If yVal2 < xVal2 Then Return 1

    Return 0
End Function
鉴于以下数据:

{"207.5,1", "373,2", "278.5,3", "9.1,1",
"9.1,9", "134,4", "277,5", "674,7", "58.5,9"}
(我添加了“9”元素,因为作为字符/数字,它们的排序将高于所有其他元素)。结果:

9.1,1
9.1,9
58.5,9
134,4
207.5,1
277,5
278.5,3
373,2
674,7


最简单的方法,至少就代码行而言,是使用允许
比较器的
排序
重载。但是,如果您经常使用这些值的数值,则应该考虑数据的类或结构。

我可以将每行字符串的内容复制到另一个可排序的容器中吗

问题不在于容器,而在于数据。数字字符串不按数值排序

Private Function ThingsCompare(x As String, y As String) As Int32
    Dim xVal As Double = Convert.ToDouble(x.Split(","c)(0))
    Dim yVal As Double = Convert.ToDouble(y.Split(","c)(0))

    If xVal < yVal Then Return -1
    If yVal < xVal Then Return 1

    ' equal, so compare segment 2
    Dim xVal2 As Double = Convert.ToDouble(x.Split(","c)(1))
    Dim yVal2 As Double = Convert.ToDouble(y.Split(","c)(1))

    If xVal2 < yVal2 Then Return -1
    If yVal2 < xVal2 Then Return 1

    Return 0
End Function
鉴于以下数据:

{"207.5,1", "373,2", "278.5,3", "9.1,1",
"9.1,9", "134,4", "277,5", "674,7", "58.5,9"}
(我添加了“9”元素,因为作为字符/数字,它们的排序将高于所有其他元素)。结果:

9.1,1
9.1,9
58.5,9
134,4
207.5,1
277,5
278.5,3
373,2
674,7


使用LINQ和Lambda表达式

Dim input = {
    "207.5,1",
    "373,2",
    "278.5,3",
    "134,4",
    "277,5",
    "674,7",
    "58.5,9"
}

' orderedResult is a IOrderedEnumerable(Of String)
Dim orderedResult = input.
    OrderByDescending(Function(item) CDec(item.Split(","c)(0)))

' dictResult is a Dictionary(Of Integer, Decimal) 
' based on the sorted result
Dim dictResult = orderedResult.ToDictionary(
    Function(item) CInt(item.Split(","c)(1)),
    Function(item) CDec(item.Split(","c)(0)))

使用LINQ和Lambda表达式

Dim input = {
    "207.5,1",
    "373,2",
    "278.5,3",
    "134,4",
    "277,5",
    "674,7",
    "58.5,9"
}

' orderedResult is a IOrderedEnumerable(Of String)
Dim orderedResult = input.
    OrderByDescending(Function(item) CDec(item.Split(","c)(0)))

' dictResult is a Dictionary(Of Integer, Decimal) 
' based on the sorted result
Dim dictResult = orderedResult.ToDictionary(
    Function(item) CInt(item.Split(","c)(1)),
    Function(item) CDec(item.Split(","c)(0)))

String.Split(“,”)将为您提供两个部分,然后您只需使用double.Parse和int.Parse来解析数字。将它们放入结构中,并根据值对结构进行排序。或者,要圆滑,实现IComparable(或者在结构上使用任何正确的可排序接口)。String.Split(“,”)将为您提供这两个部分,然后只需将.Parse和int.Parse加倍即可解析数字。将它们放入结构中,并根据值对结构进行排序。或者,要圆滑,实现IComparable(或者在结构上使用任何正确的可排序接口)。感谢Andrew-我会优先考虑您的响应,因为它对我来说是最有意义的(正如我所说,我对这一点非常陌生),并且它在我现有的代码中工作得非常完美。还要感谢那些花时间尝试帮助的人——非常感谢!)@MalcolmHutcheon感谢您的反馈。顺便说一句,如果你真的想为数字显示“.0”,你可以将
Return$“{Number},{Index}”
行更改为
Return$“{Number:N1},{Index}”
。谢谢安德鲁-我会优先考虑你的回答,因为它对我来说是最有意义的(正如我所说的,我对这个很陌生),它在我现有的代码中工作得很好。还要感谢那些花时间尝试帮助的人——非常感谢!)@MalcolmHutcheon感谢您的反馈。顺便说一句,如果您确实想为数字显示“.0”,可以将行
Return$“{Number},{Index}”
更改为
Return$“{Number:N1},{Index}”