Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am having trouble getting the key by specifying a value. What is the best way I can achieve this?

var st1= new List<string> { "NY", "CT", "ME" };
var st2= new List<string> { "KY", "TN", "SC" };
var st3= new List<string> { "TX", "OK", "MO" };
var statesToEmailDictionary = new Dictionary<string, List<string>>();
statesToEmailDictionary.Add("[email protected]", st1);
statesToEmailDictionary.Add("[email protected]", st2);
statesToEmailDictionary.Add("[email protected]", st3);

var emailAdd = statesToEmailDictionary.FirstOrDefault(x => x.Value.Where(y => y.Contains(state))).Key;
share|improve this question

5 Answers

up vote 2 down vote accepted

The return value from FirstOrDefault will be a KeyValuePair<string, List<string>>, so to get the key, simply use the Key property. Like this:

var emailAdd = statesToEmailDictionary
    .FirstOrDefault(x => x.Value.Contains(state))
    .Key;

Alternatively, here's the equivalent in query syntax:

var emailAdd = 
    (from p in statesToEmailDictionary
     where p.Value.Contains(state)
     select p.Key)
    .FirstOrDefault();
share|improve this answer
Its throwing an error "Cannot convert expression type 'System.Collections.Generic.IEnumerable<string>' to return type 'bool' " – Krishh yesterday
@Krishh sorry, there was a mistake in my original code. See the updated answer. – p.s.w.g yesterday

I think you want:

var emailAdd = statesToEmailDictionary.FirstOrDefault(x => x.Value.Any(y => y.Contains(state))).Key;
share|improve this answer
var emailAdd = statesToEmailDictionary
    .FirstOrDefault(x => x.Value != null && x.Value.Contains(state))
    .Key;

But if you're looking for performance, I'd suggest reversing your dictionary and creating a dictionary of <state, email> to do what you're looking for.

// To handle when it's not in the results
string emailAdd2 = null;
foreach (var kvp in statesToEmailDictionary)
{
    if (kvp.Value != null && kvp.Value.Contains(state))
    {
        emailAdd2 = kvp.Key;
        break;
    }
}
share|improve this answer
any way to handle NullReferenceException? – Ilya Ivanov yesterday
I don't think so, in a one-liner at least. Edited with a non-LINQ check. It does the same thing as the LINQ one does - loops through each value until it finds one, then breaks out of the loop. If it never finds one, the original value of null is kept. – Joe Enos yesterday
1  
Actually, if you were getting a NullReferenceException, then the list itself must have been null. You can handle that inside the lambda. Updated. – Joe Enos yesterday
var temp = statesToEmailDictionary.Where( x => x.Value.Contains(state)).FirstOrDefault();
var emailAdd = temp != null ? temp.Key : string.Empty;
share|improve this answer
1  
KeyValuePair<T, U> is a struct, so temp will never be null. – p.s.w.g yesterday

This is not typical usage for dictionary - i.e. your key is state and your value is email, so it should be like this:

  var dictionary = new Dictionary<string, string> {
    { "NY", "[email protected]" },
    { "CT", "[email protected]" },
    { "ME", "[email protected]" },
    { "KY", "[email protected]" },
    { "TN", "[email protected]" },
    { "SC", "[email protected]" },
    { "TX", "[email protected]" },
    { "OK", "[email protected]" },
    { "MO", "[email protected]" }
  };
  var emailAdd = dictionary[state];
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.