.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}”
。