Reputation:
I have a dictionary named as dict_id_names
:
Dictionary<int,List<string>> dict_id_names = new Dictionary<int,List<string>();
Suppose dictionary contains 3 key-value pairs:
id = 1
: List contains names "Robin", "Rahul", "Adam", "Akhtar",
id = 2
: List contains names "Sun", "Mon", "Adam",
id = 3
: List contains names "a", "b", "c"
Now my question is that if I only have name "Adam" then how can I get the respective key / keys as 1 and 2 in the above case from the dictionary?
Upvotes: 0
Views: 87
Reputation: 109547
I'd just like to offer a different perspective, for comparative purposes.
Suppose that you are doing this reverse lookup frequently, and you want it to be better than an O(N) operation.
You can achieve that using two dictionaries instead of one. To simplify things in this example, I'll use Microsoft's pre-release MultiValueDictionary
(which you can obtain via NuGet).
This approach yields an O(1) lookup:
using System;
using System.Collections.Generic;
using System.Linq;
namespace Demo
{
internal class Program
{
public static void Main()
{
var names = new Names();
names.Add(1, "Robin");
names.Add(1, "Rahul");
names.Add(1, "Adam");
names.Add(1, "Akhtar");
names.Add(2, "Sun");
names.Add(2, "Mon");
names.Add(2, "Adam");
names.Add(3, "a");
names.Add(3, "a");
names.Add(3, "c");
Console.WriteLine("IDs for Adam:");
foreach (int id in names.IdsOf("Adam"))
Console.WriteLine(id);
}
public sealed class Names
{
readonly MultiValueDictionary<int, string> names = new MultiValueDictionary<int, string>();
readonly MultiValueDictionary<string, int> lookup = new MultiValueDictionary<string, int>();
public void Add(int id, string name)
{
names.Add(id, name);
lookup.Add(name, id);
}
public IEnumerable<int> IdsOf(string name)
{
IReadOnlyCollection<int> result;
if (lookup.TryGetValue(name, out result))
return result;
else
return Enumerable.Empty<int>();
}
public IEnumerable<string> NamesOf(int id)
{
IReadOnlyCollection<string> result;
if (names.TryGetValue(id, out result))
return result;
else
return Enumerable.Empty<string>();
}
}
}
}
Upvotes: 0
Reputation: 460048
You can use LINQ:
var keyValsWithAdamValue = dict_id_names.Where(kv => kv.Value.Contains("Adam"));
foreach(var kv in keyValsWithAdamValue)
Console.WriteLine("{0}|{1}", kv.Key, String.Join(",", kv.Value));
If you just want the ID
s you can select them and use ToList
/ToArray
to create a collection:
List<int> idsWithAdamInList = dict_id_names
.Where(kv => kv.Value.Contains("Adam"))
.Select(kv => kv.Key)
.ToList();
Note that this approach is like a loop over the dictionary. You don't benefit from the fast lookup performance of a dictionary if you're enumerating it. It's not designed for this purpose. But it's simple and readable code and perfect if performance is not so important in this case.
Upvotes: 4
Reputation: 3726
Something like -
var dict_id_names= new Dictionary<int,List<string>>();
dict_id_names.Add(1, new List<string> { "Robin", "Rahul", "Adam", "Akhtar" });
var id = dict_id_names.Where(a => a.Value.Contains("Adam")).FirstOrDefault().Key;
Upvotes: 0
Reputation: 34189
You can use the following LINQ query:
int[] ids = dict_id_names
.Where(pair => pair.Value.Contains("Adam"))
.Select(pair => pair.Key)
.ToArray();
Console.WriteLine(String.Join(',', ids)); // 1,2
It will result in an array [1, 2]
, because both of these dictionary entries contain Adam
in its string list.
Upvotes: 2
Reputation: 18127
string name = "Adam";
foreach(int key in dict_id_names.Keys)
{
List<string> valueList = dict_id_names[key];
if(valueList.Contains(name);
Console.WriteLine(id);
}
This should help.
Upvotes: 1