user4860969
user4860969

Reputation:

How to get keys from the dictionary if value is in List form?

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:

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

Answers (5)

Matthew Watson
Matthew Watson

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

Tim Schmelter
Tim Schmelter

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 IDs 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

Amit Kumar Ghosh
Amit Kumar Ghosh

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

Yeldar Kurmangaliyev
Yeldar Kurmangaliyev

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

mybirthname
mybirthname

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

Related Questions