2016-11-10 6 views
0

の作成やソート、私はと同様のデータが含まれ(文字列の)リストがあります。このリストに現在配列/配列リスト/リスト

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

を、私は2つのコマンド「は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( '、')は2つの部分を与えられます。次に、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

ありがとうAndrew - 私が(私が言ったように、これはかなり新しいです)、そして私の既存のコード内で完全に機能するので、私はあなたの応答を優先します。助けようとする時間をとった他の人にも感謝します - それは大いに感謝しています! :) –

+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 

をこれだけの並べ替えに使用する10進数に最初の番号を変換します。あなたが抽出された二つの数字を持つオブジェクトをしたい場合は、あなたが使用できます。

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 

をこれは、あなたnidxプロパティを持つ匿名型のIEnumerableをを与える - あなたは「クラスを作成し、あなたはドン場合は、代わりにそののインスタンスを作成することができます匿名型が必要です(関数から返すなど)。

1

少なくともコード行に関して最も簡単な方法は、オーバーロードを使用して、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"} 

を(文字/数字として、彼らは他のすべてよりも高くソートされますので、私は "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とラムダ式の使用

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))) 
関連する問題