2016-11-10 86 views
0

目前,我有(的字符串)的列表,其包含类似于数据:创建和排序的阵列/数组列表/列表

"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 

我试图尽可能多的迭代我能想到的(相当新的这个所以大概错过了很明显的!)。如果可以的话请帮忙!谢谢。

+1

String.Split(',')会给你两个部分,然后你需要的只是double.Parse和int.Parse来解析数字。将它们放在结构中并根据值对结构进行排序。或者,光滑一些,并实现IComparable(或任何正确的可排序接口在结构上使用)。 – Will

回答

0

如果你打算多次使用数据,那么有一个代表它的类是有意义的。通过这种方式,您可以为零件提供有意义的名称,有一种简单的方法来创建一个新项目,轻松操作数据,并将其转换为字符串。

它可能看起来像繁琐的代码加载,但你只需要编写一次,那么你的生活简单得多,当你要使用的数据:

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 

输出:

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

谢谢安德鲁 - 我会优先考虑你的回应,因为它对我来说是最有意义的(正如我所说的,我对此很新),并且它在我现有的代码中完美地工作。也感谢那些花时间去尝试帮助的人 - 非常感谢! :) –

+0

@MalcolmHutcheon感谢您的反馈。顺便说一句,如果你真的想要显示数字的“.0”,你可以把'Return $'{Number},{Index}'''换成'Return $'{Number:N1},{Index}“ '。 –

1

你可以使用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 

这给你一个IEnumerable的匿名类型与nidx性能 - 而不是如果你不,你可以创建一个类,并在其中创建实例”你想要匿名类型(例如你需要从函数中返回)。

1

至少就代码行而言,最简单的方法是使用Sort过载,该过载允许Comparer。但是,如果您经常使用这些数值来处理这些事情,则应该考虑数据的类或结构。

可以予每行的字符串的内容复制到另一个可排序容器

的问题是不是容器,但数据。数字串不按数字值排序。

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 

用法:

things.Sort(AddressOf ThingsCompare) 

鉴于以下数据:

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

(I添加了 “9” 元素,因为作为字符/数字,他们将排序比所有其他更高) 。结果:

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

1

使用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)))