2010-09-03 13 views
3

J'ai deux dictionnaires commefusion de dictionnaires dans le niveau clé, puis au niveau de la valeur

Dictionary<String, String> one = new Dictionary<string, string> 
{ 
    { "A", "1" }, 
    { "B", "2" }, 
    { "C", "3" }, 
    { "D", "4" }, 
    { "E", "5" }, 
    { "F", "6" }, 
    { "G", "7" }, 
    { "H", "8" } 
}; 

Dictionary<String, String> two = new Dictionary<string, string> 
{ 
    { "A", "1" }, 
    { "B", "2" }, 
    { "C", "3" }, 
    { "E", "4" }, 
    { "F", "4" }, 
    { "I", "6" }, 
    { "J", "10" }, 
    { "K", "11" } 
}; 

i doivent fusionner les deux dictionnaire niveau clé, puis au niveau de valeur et d'ajouter le dictionnaire résultant dans le nouveau dictionnaire three, le dictionnaire résultant ne devrait pas avoir mêmes touches ou mêmes valeurs et dans ce cas le dictionnaire résultant est comme

Dictionary<String, String> three = new Dictionary<string, string> 
{ 
    { "A", "1" }, 
    { "B", "2" }, 
    { "C", "3" }, 
    { "D", "4" }, 
    { "E", "5" }, 
    { "F", "6" }, 
    { "G", "7" }, 
    { "H", "8" }, 
    { "J", "10" }, 
    { "K", "11" } 
}; 

maintenant, je suis en utilisant comme

  1. Union toutes les clés dans les deux dictionnaires
  2. Création d'un nouveau dictionnaire avec les nouvelles clés
  3. enlever les valeurs dupicate (mêmes valeurs)

EDIT: si les deux dictionnaires ayant la même clé paire de valeurs puis j'ai besoin de stocker la paire de valeur de clé du premier dictionnaire.

est-il un moyen de le faire en utilisant LINQ? Merci à l'avance

+0

Lorsque les touches sont identiques dans les dictionnaires, vous voulez stocker la valeur dans le premier dictionnaire 6? – Santhosh

+0

oui. Si les deux dictionnaires ayant la même paire de valeurs de clé, alors j'ai besoin de stocker la paire de valeurs de clé du premier dictionnaire –

+2

Vous devez spécifier les règles de résolution de collision plus précisément. – Ani

Répondre

2

Une option, en utilisant le fait qu'un dictionnaire est une séquence de paires clé/valeur:

var dictionary = dictionary1.Concat(dictionary2) 
          .ToLookup(pair => pair.Key, pair => pair.Value) 
          .ToDictionary(x => x.Key, x => x.First()); 

Ce n'est pas très efficace, il est vrai (comme il construit essentiellement une table de hachage deux fois) mais je crois que ça va marcher.

+0

@ Jon Skeet: merci, je dois supprimer les valeurs en double de "dictionnaire". Comme je l'ai mentionné, le dictionnaire résultant ne doit pas contenir la même clé ou la même valeur –

+0

@Pramodh: Voir ma réponse où distinct a lieu – abatishchev

+0

Jon, pourriez-vous s'il vous plaît décrire ce que pour 'ToLookup()' avez-vous utilisé? – abatishchev

1
var three = new Dictionary<string, string>(); 
foreach(var kvp in two.Concat(one)) 
    three[kvp.Key] = kvp.Value; 

Ceci est assez efficace, mais je ne suis pas sûr si c'est la sortie que vous voulez; l'énoncé du problème n'est pas assez clair.

EDIT: Si vous souhaitez ensuite supprimer les doublons valeurs de three:

var keysWithDuplicateValues = three.ToLookup(kvp => kvp.Value, kvp => kvp.Key) 
            .SelectMany(group => group.Skip(1)) 
            .ToList(); 

foreach(var key in keysWithDuplicateValues) 
    three.Remove(key); 

Notez que cela vaut mieux que d'enlever avec impatience les clés en double et valeurs en double au début, parce que certains les collisions peuvent être résolues automatiquement.

1

Une méthode linq-only consisterait à concaténer les deux dictionnaires et à replier la suite résultante de clé/valeurs en un seul résultat. Cela remplace les valeurs de toutes les clés de dict2 qui sont aussi dans dict1: comme vous l'avez fait pour F

var dict3 = dict2.Concat(dict1) 
    .Aggregate(new Dictionary<string, string>(), (d, kvp) => { 
     d[kvp.Key] = kvp.Value; 
     return d; 
    }); 
1
class StringKeyValuePairEqualityComparer : IEqualityComparer<KeyValuePair<string, string>> 
{ 
    public bool Equals(KeyValuePair<string, string> x, KeyValuePair<string, string> y) 
    { 
     return x.Key == y.Key; 
    } 

    public int GetHashCode(KeyValuePair<string, string> obj) 
    { 
     return obj.Key.GetHashCode(); 
    } 
} 

var three = Enumerable.Concat(one, two) 
       .Distinct(new StringKeyValuePairEqualityComparer()) 
       .ToDictionary(p => p.Key, p => p.Value); 

int count = three.Keys.Count; // 11 
Questions connexes