Сортировка ConcurrentDictionary по значению - PullRequest
11 голосов
/ 22 декабря 2011

Я могу отсортировать свой ConcurrentDictionary по значению примерно так:

static ConcurrentDictionary<string, Proxy> Proxies = 
    new ConcurrentDictionary<string, Proxy>();

Proxies.OrderBy(p => p.Value.Speed);

Что здорово, за исключением того, что я хочу установить новый переупорядоченный список в качестве словаря, эффективно сортируя словарь, а не просто получая список результатов отсортированных элементов.

Я пытаюсь сделать что-то подобное, но безуспешно - словарь все еще не упорядочен после:

Proxies = new ConcurrentDictionary<string,Proxy>(
    Proxies.OrderBy(p => p.Value.Speed));

Кажется, что это не влияет на словарь. Я также попытался привести результат OrderBy к новому варианту, полагая, что он может повлиять на делегата, но все же не повезло.

Как я могу переупорядочить этот ConcurrentDictionary и затем заставить словарь быть переупорядоченным результатом из OrderBy?

Ответы [ 5 ]

9 голосов
/ 22 декабря 2011

Простые словари не отсортированные коллекции. Это просто коллекция, которая отображает ключи на значения. ConcurrentDictionary ничем не отличается.

Вместо этого вам понадобится SortedConcurrentDictionary (сродни SortedDictionary), однако эта структура данных не существует.

А если вам действительно нужен отсортированный «словарь», нам нужно больше узнать о вашем случае использования. Это очередь с поддельными приоритетами? Не могли бы вы просто использовать ConcurrentBag<Proxy> и выполнить заказ по факту?

Если вам нужно взять коллекцию и в параллельном параллельном методе использовать прокси в отсортированном порядке, я предлагаю взглянуть на создание пользовательского Partitioner , потенциально заимствуя из примера MSDN OrderablePartitioner .

2 голосов
/ 18 ноября 2012

Может быть неэффективно, если вы часто его называете в неизменяемом классе, но просто:

Imports System.Collections.Concurrent

Public Class SortedConcurrentDictionary(Of TKey, Tvalue)
Inherits ConcurrentDictionary(Of TKey, Tvalue)

    Shadows ReadOnly Property Values As IEnumerable(Of Tvalue)
        Get
            If MyBase.Values.Count = 0 Then
                Return MyBase.Values
            End If
            Return From k In Keys Order By k Select Me(k)
        End Get
    End Property
End Class
2 голосов
/ 23 декабря 2011

Решением является использование SortedSet<T>, обнаруженного после многих часов исследований и пересмотра кода.Сортированный набор предлагает уникальность Dictionary или HashSet, но также позволяет сортировать - ни Dictionary, ни HashSet не позволяют сортировку.

2 голосов
/ 22 декабря 2011

Словарь, особенно ConcurrentDictionary, по существу не отсортирован.

Если вам нужна отсортированная коллекция, вам нужно сохранить значения в другом типе, например SortedDictionary<T,U>.

0 голосов
/ 22 декабря 2011

ConcurrentDictionary, так же как и Dictionary, не знает концепции сортировки, то есть не содержит никакой информации о заказе.Результат OrderBy() имеет определенный порядок, но при присвоении Proxies информация о заказе теряется.

Обратите внимание, что существуют отсортированные реализации IDictionary, а именно SortedDictionary и SortedList.

...