2015-10-27 3 views
1

У меня есть два словаря различной длины. Клавиши в обоих словарях идентичны, и значения могут не совпадать.Пересечение двух списков словаря по значениям только определенных ключей C#

var A = List<Dictionary<string, object>>(); 
var B = List<Dictionary<string, object>>(); 

Я хотел бы пересекаться А и В унижен от значений 3 ключа в в словаре объекта, содержащегося в них.

Для например:

var dict = new Dictionary<string,object>{{"W",val1},{"X",val2},{"Y",val3},{"Z",val4}} 

словарь аналогичен изложенному содержится в списке А и В с различными значениями для знач1, val2, val3, val4. Я хочу пересечь A и B, если значения для ключей W, X, Y равны, но я не забочусь о значении в Z для пересечения. Есть ли способ добиться этого элегантно?

Разрабатывая с примером:

A.add(new Dictionary<string,object>{{"W",123},{"X",456},{"Y",789},{"Z",103}}); 
    A.add(new Dictionary<string,object>{{"W",124},{"X",456},{"Y",789},{"Z",893}}); 
    A.add(new Dictionary<string,object>{{"W",123},{"X",456},{"Y",789},{"Z",134}}); 

    B.add(new Dictionary<string,object>{{"W",123},{"X",456},{"Y",789},{"Z",900}}); 
    B.add(new Dictionary<string,object>{{"W",124},{"X",456},{"Y",789},{"Z",893}}); 
    B.add(new Dictionary<string,object>{{"W",212},{"X",321},{"Y",789},{"Z",134}}); 

Если я A.intersect (B), я хотел бы получить следующий список назад

{"W",123},{"X",456},{"Y",789},{"Z",103} 
{"W",123},{"X",456},{"Y",789},{"Z",900} 
{"W",124},{"X",456},{"Y",789},{"Z",893} 
+0

Я не уверен, что понял вопрос. Можете ли вы привести пример того, какой желаемый результат будет в этом случае? – MikeTheLiar

+1

Подождите, что? У вас есть два списка словарей? –

+0

Что вы подразумеваете под пересечением? –

ответ

2

Это даст вам IEnumerable:

var c=A.Select(a=>new {W=a[W],X=a[X],Y=a[Y]}) 
    .Intersect(B.Select(a=>new {W=a[W],X=a[X],Y=a[Y]})); 

с другой стороны, создать себе обычай IEqualityComparer, а затем вы можете сделать это:

var c=A.Intersect(B,new MyComparer()); 

что-то вроде:

class MyComparer : IEqualityComparer<Dictionary<string,object>> 
{ 
    public bool Equals(Dictionary<string,object> b1, Dictionary<string,object> b2) 
    { 
     if (b2 == null && b1 == null) 
      return true; 
     else if (b1 == null || b2 == null) 
      return false; 
     else if(b1["W"]==b2["W"] && b1["X"]==b2["X"] && b1["X"]==b2["X"]) 
      return true; 
     else 
      return false; 
    } 

    public int GetHashCode(Dictionary<string,object> bx) 
    { 
     int hCode = bx["W"]^bx["X"]^bx["Y"]; 
     return hCode.GetHashCode(); 
    } 
} 
+0

Незначительные изменения могут потребоваться для получения хэш-кода из bx ["W"] и т. Д., Так как это объект. W, X, Y следует указывать в первом примере, если они действительно являются строками, а не просто именами имен заполнителей. –

+0

отлично работает, просто быстро отслеживается. Будет ли это работать, если я хочу такое же поведение, но как с помощью вычитания с использованием за исключением? – Trancey

+1

Да. Но если вы делаете то и другое, я бы действительно предложил использовать IEqualityComparer или создать собственный тип, который наследуется от словаря , чтобы вы могли напрямую реализовать интерфейсы. Тогда вам даже не понадобится поставлять IEqualityComparer вообще, и просто разрешите работу по умолчанию. –

Смежные вопросы