【问题标题】:How to sort SortedDictionary by values in .NET 2.0?如何按 .NET 2.0 中的值对 SortedDictionary 进行排序?
【发布时间】:2015-03-11 09:34:27
【问题描述】:

我有一个 SortedDictionary:

Dim myFilterItems As SortedDictionary(Of String, FilterItem)
myFilterItems = New SortedDictionary(Of String, FilterItem)(StringComparer.CurrentCultureIgnoreCase)

FilterItem 类的定义如下:

Private Class FilterItem
    Public ValueToSort As Object
    Public IsChecked As Boolean
    Public IsAbsent As Boolean = False
End Class

我需要枚举按 FilterItem.ValueToSort 属性排序的 SortedDictionary。使用 LINQ,很容易做到——我们得到对应的 IEnumerable,然后使用 For Each:

Dim mySortedValueList As IEnumerable(Of KeyValuePair(Of String, FilterItem))
mySortedValueList = From entry In myFilterItems Order By entry.Value.ValueToSort Ascending
For Each entry As KeyValuePair(Of String, FilterItem) In mySortedValueList
    ' ...
Next

如何在 .NET 2.0 中有效地做到这一点?

【问题讨论】:

  • 您基本上不使用 SortedDictionary。 SortedDictionary 被定义按键排序,而不是按值排序。
  • @JonSkeet,我很乐意使用另一种集合,但在我提出的任务之前,我正在使用按键排序的 SortedDictionary 做很多工作。我使用 SortedDictionary.ContainsKey() 方法来分析一个键是否已经在字典中,同时枚举 100'000+ 行原始数据。
  • 这并不意味着 SortedDictionary 是正确的答案。如果需要,您可以将键/值对复制到列表中,然后使用自定义比较器对列表进行排序。 (顺便说一句,您真的与 .NET 2.0 绑定吗?我会非常担心,如果没有别的安全更新的话……请注意,有 LINQ to Objects 实现也适用于 .NET 2.0...)
  • 是的,我真的与 .NET 2.0 紧密相关。现有代码适用于 .NET 3.5+,但现在我们需要使其适用于 .NET 2.0,因为我们不允许在这些电脑上升级到 .NET 3.5。
  • 那我建议你使用我之前建议的列表方式。但我会非常担心那些被告知旧的、可能不安全的软件的 PC :(

标签: vb.net linq sorting .net-2.0 sorteddictionary


【解决方案1】:

我按照 Jon Skeet 的建议使用 Lists 重写了我的代码。从我的测试中可以看出,我的性能与 LINQ 查询相同——甚至提高了 5-10%。新版代码如下:

Dim mySortedValueList As New List(Of KeyValuePair(Of String, FilterItem))(myFilterItems)
If iArr <> iGAFMValueType.Text Then
    mySortedValueList.Sort(AddressOf CompareFilterItemsByValuesToSort)
End If

Private Shared Function CompareFilterItemsByValuesToSort(ByVal itemX As KeyValuePair(Of String, FilterItem), ByVal itemY As KeyValuePair(Of String, FilterItem)) As Integer
    Dim myValueX As IComparable = TryCast(itemX.Value.ValueToSort, IComparable)
    Dim myValueY As IComparable = TryCast(itemY.Value.ValueToSort, IComparable)
    If (myValueX Is Nothing) Then
        If (myValueY Is Nothing) Then
            Return 0
        End If
        Return -1
    End If
    If (myValueY Is Nothing) Then
        Return 1
    End If

    Dim myTypeX As Type = myValueX.GetType()
    Dim myTypeY As Type = myValueY.GetType()
    If (myTypeX <> myTypeY) Then
        Return String.CompareOrdinal(myTypeX.Name, myTypeY.Name)
    End If

    Return myValueX.CompareTo(myValueY)
End Function

但是,在研究此比较算法时,我发现我无法比较某些数字类型的值 - 尽管它们可以进行比较(例如,SByte 和 Double 值)。顺便说一句,在这种情况下,原始 LINQ 查询也会失败。但这是在这个问题中继续的另一个故事:

How to compare two numeric values (SByte, Double) stored as Objects in .NET 2.0?

【讨论】:

    猜你喜欢
    • 2011-02-06
    • 2019-03-31
    • 1970-01-01
    • 1970-01-01
    • 2012-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-08
    相关资源
    最近更新 更多