2012-09-12 7 views
6

Ho un oggetto Array di Person e voglio convertirlo in un ConcurrentDictionary. C'è un metodo di estensione per convertire uno Array in un Dictionary. Esiste un metodo di estensione per convertire uno Array in un ConcurrentDictionary?Un modo migliore per convertire array in dizionario concorrente usando linq o IEnumarable?

public class Person 
{ 
    public Person(string name, int age) 
    { 
     Name =name; 
     Age = age; 
    } 

    public string Name { get; set; } 
    public int Age { get; set; } 
} 

Dictionary<int, Person> PersonDictionary = new Dictionary<int, Person>(); 
Person[] PersonArray = new Person[] 
{ 
    new Person("AAA", 30), 
    new Person("BBB", 25), 
    new Person("CCC",2), 
    new Person("DDD", 1) 
}; 

PersonDictionary = PersonArray.ToDictionary(person => person.Age); 

Qualunque simile espressione metodo di estensione/lambda per convertire una Array ad un ConcurrentDictionary?

risposta

15

Certo, utilizzare il costruttore che accetta un IEnumerable<KeyValuePair<int,Person>>:

var personDictionary = new ConcurrentDictionary<int, Person> 
         (PersonArray.ToDictionary(person => person.Age)); 

var deduce il tipo di ConcurrentDictionary<int,Person>.

Se avete intenzione di creare un metodo di estensione, come suggerito Vespa, mi consiglia di utilizzare la seguente versione, che offre una sintassi un po 'più fluente:

public static ConcurrentDictionary<TKey, TValue> ToConcurrentDictionary<TKey, TValue> 
(this IEnumerable<TValue> source, Func<TValue, TKey> valueSelector) 
{ 
    return new ConcurrentDictionary<TKey, TValue> 
       (source.ToDictionary(valueSelector)); 
} 

L'utilizzo è simile al ToDictionary, creando una sensazione costante:

var dict = PersonArray.ToConcurrentDictionary(person => person.Age); 
+1

Mentre questa risposta è valida, [la risposta di Wasp] (http://stackoverflow.com/a/12396386/1149773) è superiore in termini di esigenze computazionali e di memoria. Questa risposta richiede la costruzione di un dizionario , che verrà immediatamente scartato. – Douglas

2

C'è una constructor che prende IEnumerable<KeyValuePair<TKey,TValue>>

IDictionary<int,Person> concurrentPersonDictionary = 
    new ConcurrentDictionary<int,Person>(PersonArray.ToDictionary(person => person.Age)); 
9

si può scrivere il proprio metodo di estensione molto facilmente, per esempio come questi:

public static class DictionaryExtensions 
{ 
    public static ConcurrentDictionary<TKey, TValue> ToConcurrentDictionary<TKey, TValue>(
     this IEnumerable<KeyValuePair<TKey, TValue>> source) 
    { 
     return new ConcurrentDictionary<TKey, TValue>(source); 
    } 

    public static ConcurrentDictionary<TKey, TValue> ToConcurrentDictionary<TKey, TValue>(
     this IEnumerable<TValue> source, Func<TValue, TKey> keySelector) 
    { 
     return new ConcurrentDictionary<TKey, TValue>(
      from v in source 
      select new KeyValuePair<TKey, TValue>(keySelector(v), v)); 
    } 

    public static ConcurrentDictionary<TKey, TElement> ToConcurrentDictionary<TKey, TValue, TElement>(
     this IEnumerable<TValue> source, Func<TValue, TKey> keySelector, Func<TValue, TElement> elementSelector) 
    {    
     return new ConcurrentDictionary<TKey, TElement>(
      from v in source 
      select new KeyValuePair<TKey, TElement>(keySelector(v), elementSelector(v))); 
    } 
} 
+0

questo è un buon suggerimento, +1. Solo due critiche minori: il parametro può essere di tipo 'IEnumerable >' e suggerisco di seguire la convenzione di denominazione standard di 'TKey, TValue'. – Adam

+0

D'accordo, il tipo potrebbe essere fatto come hai detto, lo aggiusterò. Il mio punto era più chiaro per chiarire che un tale metodo di estensione, se mancante, è molto facile da aggiungere. – Wasp

+0

oops. sembra che avevamo in mente cose simili; vedere la mia risposta;) – Adam

Problemi correlati