2016-11-10 55 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)))