2013-06-05 2 views
1

У меня есть это, но это так коротка, я почти уверен, что я что-то не хватает:Как проверить, содержат ли два словаря одинаковые значения?

public static bool ValueEquals<TKey, TValue> 
    (this IDictionary<TKey, TValue> source, IDictionary<TKey, TValue> toCheck) 
{ 
    if (object.ReferenceEquals(source, toCheck)) 
     return true; 
    if (source == null || toCheck == null || source.Count != toCheck.Count) 
     return false; 
    return source.OrderBy(t => t.Key).SequenceEqual(toCheck.OrderBy(t => t.Key)); 
} 

Так в основном, если они имеют одинаковую ссылку, вернитесь true. Если любой из них null или их количество отличается, верните false. Затем верните, если последовательности (упорядоченные по их ключам, а затем их значения) совпадают. I должен что-то упустить, поскольку он слишком короткий, чтобы быть достаточно хорошим.

+0

Извините! Я случайно нажал кнопку! Это еще не закончено! –

+2

Чтобы уточнить, вы хотите иметь одинаковые значения * для тех же клавиш *? (Заголовок вопроса только упоминает значения, которые отличаются.) –

+0

@JonSkeet Я имел в виду значения как в общем смысле, а не в значении значения словаря. Поэтому, если у меня было два словаря 'string' и' bool', и они были '{" true ", true}, {" false ", false}", а другая была '{" false ", false}, { «true», true} ', они будут равны. Извините за двусмысленность. –

ответ

4

Да, ваш код будет работать, если все ключи реализуют IComparable, и оба ключа и значения имеют метод Equals, который сравнивает то, что вы хотите сравнить. Если либо ключи, либо значения не имеют соответствующих реализаций этих методов, то это не сработает.

Ваш метод также не предоставляет функциональных возможностей для настраиваемых объектов IComparer или IEqualityComparer объектов, подлежащих передаче, для учета случаев, когда объект не имеет желательной реализации одного из этих методов. Будь то проблема в вашем конкретном случае, мы не можем сказать.

Ваше решение также должно сортировать все значения, что несколько менее эффективен, чем другие возможные реализации множество равных, но это не резко хуже, так что если у вас нет особо крупных коллекций, которые не должен» Это огромная проблема.

Метод с сопоставимой функциональности вашему, но увеличена скорость будет (сохраняя первые две проверки у вас есть):

return !source.Except(toCheck).Any(); 

Поскольку этот метод не зависит от сортировки также обеспечивает преимущество не нуждаясь TKey для реализации IComparable.

Основной причиной того, что и этот метод и ваш метод работает, из-за того, что KeyValuePair переопределяет это определение Equals и GetHashCode к должен быть основан на его собственной ссылки, а на ключ и значение его заворачивает. Два значения KeyValuePairs равны, если оба ключа и значения равны, а хэш-код содержит хеш-код как ключа, так и значения.

+0

Спасибо за это :) –

+0

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

+0

@supercat Это сделало бы это быстрее в случае, когда они будут отличаться и медленнее в случае, если они одинаковы, но я буду включать оба, как вы правы, это может стоить того. – Servy

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