Spencer R
Spencer R

Reputation: 1158

Determine if Dictionary Contains All of a Set of Keys

I'm trying to figure out the best way to determine if a Dictionary<string, string> object contains all of a set of string objects as keys.

I'm probably not making any sense so here's some example code using a definite set of strings:

public static bool ContainsKeys(this Dictionary<string, string> dictionary)
{
  return dictionary.ContainsKey("fname") && dictionary.ContainsKey("lname") && dictionary.ContainsKey("address1") &&
         dictionary.ContainsKey("city") && dictionary.ContainsKey("state") && dictionary.ContainsKey("zip");
}

The idea here is to accept an arbitrary set of strings as keys and check if the keys of the Dictionary<string, string> object contain all of the strings in keys.

I was trying to go down the LINQ road with this:

public static bool ContainsKeys(this Dictionary<string, string> dictionary, string[] keys)
{
  var query = from entry in dictionary
              where keys.Contains(entry.Key)
              select entry;

  return query.Any();
}

I have no idea if I'm on the right path though - I think this might work if I wanted to know if dictionary contained any of those strings as keys.

Upvotes: 22

Views: 19351

Answers (5)

Robert McLaws
Robert McLaws

Reputation: 2582

To expand on the accepted answer, here is the complete source code for an extension method that will work on ANY type of Dictionary, not just one with string keys:

using System.Linq;

namespace System.Collections.Generic
{

    /// <summary>
    /// 
    /// </summary>
    public static class IDictionaryExtensions
    {

        public static bool ContainsKeys<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, IEnumerable<TKey> keys)
        {
            return keys.Any() && keys.All(key => dictionary.ContainsKey(key));
        }

    }

}

Upvotes: 1

Joachim Isaksson
Joachim Isaksson

Reputation: 180917

This should do it, just use Except to eliminate the keys that are in the Dictionary and check if anything is left over;

return !keys.Except(dictionary.Keys).Any();

Upvotes: 2

yoozer8
yoozer8

Reputation: 7489

This can be done pretty simply using the All extension method.

return keys.All(k => dictionary.ContainsKey(k));

This will check that the given predicate (dictionary.ContainsKey(k)) is true for all keys in the given array.

Upvotes: 6

GraemeF
GraemeF

Reputation: 11457

LINQ is indeed good for this sort of thing:

public static bool ContainsKeys(this Dictionary<string, string> dictionary, string[] keys)
{
  return keys.All(dictionary.ContainsKey);
}

Upvotes: 4

Anthony Pegram
Anthony Pegram

Reputation: 126834

Something like this should meet your requirement. Apply proper validations around your arguments, of course.

return keys.Any() 
    && keys.All(key => dictionary.ContainsKey(key));

Note: I include Any because All will return true if the source sequence (keys) is actually empty. If you don't mind this, then eliminate the use of Any.

Upvotes: 33

Related Questions