2012-09-12 15 views
6

Tengo un objeto Array de Person y quiero convertirlo a ConcurrentDictionary. Hay un método de extensión para convertir un Array en un Dictionary. ¿Hay algún método de extensión para convertir un Array en un ConcurrentDictionary?¿Alguna mejor forma de convertir una matriz a un diccionario simultáneo 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); 

Cualquier expresión método de extensión/lambda similar para convertir una Array a un ConcurrentDictionary?

Respuesta

15

Claro, utilice el constructor que acepta un IEnumerable<KeyValuePair<int,Person>>:

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

var infiere el tipo de ConcurrentDictionary<int,Person>.

Si va a crear un método de extensión, como lo sugiere la avispa, yo recomendaría usar la siguiente versión que ofrece una sintaxis un poco más fluida:

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

el uso es similar a la ToDictionary, creando una organización coherente:

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

Si bien esta respuesta es válida, [respuesta de Wasp] (http://stackoverflow.com/a/12396386/1149773) es superior en términos de demandas de cómputo y memoria. Esta respuesta requiere un 'Diccionario ' para construir, solo para ser descartado inmediatamente. – Douglas

2

Hay una constructor que toma IEnumerable<KeyValuePair<TKey,TValue>>

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

Usted puede escribir su propio método de extensión muy fácilmente, por ejemplo como los siguientes:

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

esa es una buena sugerencia, +1. Solo dos críticas menores: el parámetro puede ser del tipo 'IEnumerable >' y sugiero seguir la convención de nomenclatura estándar de 'TKey, TValue'. – Adam

+0

De acuerdo, el tipo podría hacerse como usted dijo, lo arreglaré. Mi punto era más bien aclarar que ese método de extensión, si falta, es muy fácil de agregar. – Wasp

+0

oops. parece que teníamos cosas similares en mente; ver mi respuesta;) – Adam

Cuestiones relacionadas