创建和排序数组/ arraylist / list

时间:2016-11-10 17:42:40

标签: .net arrays vb.net list sorting

目前,我有一个List(of String),其中包含类似于:

的数据
"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

我已经尝试了尽可能多的迭代(我对此很新,所以很可能错过了非常明显的!)。如果可以的话请帮忙!感谢。

4 个答案:

答案 0 :(得分: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 :(得分:1)

至少就代码行而言,最简单的方法是使用允许Sort的{​​{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)

(我添加了&#34; 9&#34;元素因为字符/数字排序高于所有其他元素)。结果:

  

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

答案 2 :(得分: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)))

答案 3 :(得分: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