0

I have a dictionary with two key value pairs. I want to compare the values and return true if the items match irrespective of the order of the int[].

This is what I have:

var d1 = new Dictionary<string, List<int>>(); d1.Add("Inputs", [1,2,3,4]) d1.Add("Outputs", [2,3,1,4]) 

My code is as:

if (d1["Inputs"].SequenceEqual(d1["Outputs"])) { return true } else { return false } 

I want to return true in this case but it returns false. Please advise.

9
  • Use. HashSet.SetEquals instead of a List. Commented Jun 23, 2020 at 23:22
  • @Dai My dictionary is being set by reading contents from an excel file. I have no hold on the dictionary values. Is there a way to do an item compare? Commented Jun 23, 2020 at 23:23
  • 5
    You could sort the lists first. Commented Jun 23, 2020 at 23:25
  • 1
    When you say "if the items match" do you mean only if an item appears in both lists, or does the count of each list also need to match? Commented Jun 23, 2020 at 23:36
  • 1
    Except will remove any duplicates, so likely not. Commented Jun 23, 2020 at 23:57

2 Answers 2

2

You can use OrderBy to order each collection, and then use SequenceEqual to determine if they have the same number of items, in the same order:

var areEqual = d1["Inputs"].OrderBy(i => i).SequenceEqual(d1["Outputs"].OrderBy(i => i)); 
Sign up to request clarification or add additional context in comments.

Comments

1

This is answered well by @Rufus.

However, here is an extension method for your OCD pleasure. Validates input, returns false on key not found (which you may want as an KeyNotFoundException, depending on your fault tolerance level)

Given

public static class Extensions { private static bool CompareValues<T>( this IReadOnlyDictionary<string, List<T>> source, string key1, string key2) { if (source is null) throw new ArgumentNullException(nameof(source)); if (string.IsNullOrWhiteSpace(key1)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(key1)); if (string.IsNullOrWhiteSpace(key2)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(key2)); if (!source.TryGetValue(key1, out var list1)) return false; if (!source.TryGetValue(key2, out var list2)) return false; return Enumerable.SequenceEqual( list1.OrderBy(x => x), list2.OrderBy(x => x) ); } } 

Usage

var result = d1.CompareValues("Inputs","outputs") 

3 Comments

Thanks for your tips earlier regarding my inefficient solution (that would also give false "positives"). Since you pointed out that my solution "would a be quadratic time complexity at worst" would it not be prudent in your solution to also check length before using two OrderBy and the SequenceEqual?
hi @Barns SequenceEqual actually does that step "true if the two source sequences are of equal length and their corresponding elements are equal according to the default equality comparer for their type;"
Guess I should have read the docs on SequenceEqual before I mentioned it. Thank, again! I learned something new.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.