2012-09-12 2 views
6

J'ai un objet Array de Person et je veux le convertir en un ConcurrentDictionary. Il existe une méthode d'extension pour convertir un Array en Dictionary. Existe-t-il une méthode d'extension pour convertir un Array en un ConcurrentDictionary?Une meilleure façon de convertir un tableau en dictionnaire concurrent en utilisant linq ou 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); 

Toute expression méthode d'extension analogue/lambda pour convertir un Array à un ConcurrentDictionary?

Répondre

15

Bien sûr, utilisez le constructeur qui accepte un IEnumerable<KeyValuePair<int,Person>>:

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

var infère le type à ConcurrentDictionary<int,Person>.

Si vous allez créer une méthode d'extension, comme Wasp a suggéré, je vous conseille d'utiliser la version suivante qui offre une syntaxe un peu plus fluide:

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'utilisation est similaire à la ToDictionary, la création une organisation cohérente:

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

Bien que cette réponse soit valide, [la réponse de Wasp] (http://stackoverflow.com/a/12396386/1149773) est supérieure en termes de demandes de calcul et de mémoire. Cette réponse nécessite la construction d'un 'Dictionary ' pour être immédiatement rejeté. – Douglas

2

Il y a un constructor qui prend IEnumerable<KeyValuePair<TKey,TValue>>

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

Vous pouvez écrire votre propre méthode d'extension très facilement, par exemple comme ceux-ci:

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

c'est une bonne suggestion, +1. Juste deux critiques mineures: le paramètre peut être de type 'IEnumerable >' et je suggère de suivre la convention de nommage standard de 'TKey, TValue'. – Adam

+0

D'accord, le type pourrait être fait comme vous l'avez dit, je vais le réparer. Mon point était plus de préciser qu'une telle méthode d'extension, si elle est manquante, est très facile à ajouter. – Wasp

+0

oups. semble que nous avions des choses semblables à l'esprit; voir ma réponse;) – Adam

Questions connexes