awe
awe

Reputation: 22462

How to filter on a list of keys in a Dictionary using LINQ

I have this dictionary mappings declared as a Dictionary<string, HashSet<string>>.
I also have this method to do stuff on a hashset in the dictionary:

public void DoStuff(string key, int iClassId){
    foreach (var classEntry in
             from c in mappings[key]
             where c.StartsWith(iClassId + "(")
             select c)
    {
        DoStuffWithEntry(classEntry);
    }
}

private void DoStuffWithEntry(string classEntry){
    // Do stuff with classEntry here
}

In one case, I need to do this on a number of keys in the mappings dictionary, and I was thinking it was better to rewrite and filter on a list of keys instead of calling DoStuff for each key to optimise the execution.

Currently I do this:

DoStuff("key1", 123);
DoStuff("key2", 123);
DoStuff("key4", 123);
DoStuff("key7", 123);
DoStuff("key11", 123);

Logically something like this instead of calling DoStuff for each (FilterOnKeys is not a method - just what I want...):

    foreach (var classEntry in
             from c in mappings.FilterOnKeys("key1", "key2", "key4", "key7", "key11")
             where c.StartsWith(iClassId + "(")
             select c)
    {
        DoStuffWithEntry(classEntry);
    }

Upvotes: 0

Views: 3753

Answers (4)

B.Balamanigandan
B.Balamanigandan

Reputation: 4875

I'm using LINQ as per your requirement

var temp = eid.Select(i => 
            EmployeeList.ContainsKey(i) 
            ? EmployeeList[i]
            : null
        ).Where(i => i != null).ToList();

The Complete C# Source Code is

public class Person
{
    public int EmpID { get; set; }
    public string Name { get; set; }
    public string Department { get; set; }
    public string Gender { get; set; }
}

void Main()
{   
    Dictionary<int, Person> EmployeeList = new Dictionary<int, Person>();
    EmployeeList.Add(1, new Person() {EmpID = 1, Name = "Peter", Department = "Development",Gender = "Male"});
    EmployeeList.Add(2, new Person() {EmpID = 2, Name = "Emma Watson", Department = "Development",Gender = "Female"});
    EmployeeList.Add(3, new Person() {EmpID = 3, Name = "Raj", Department = "Development",Gender = "Male"});
    EmployeeList.Add(4, new Person() {EmpID = 4, Name = "Kaliya", Department = "Development",Gender = "Male"});
    EmployeeList.Add(5, new Person() {EmpID = 5, Name = "Keerthi", Department = "Development",Gender = "Female"});

    List<int> eid = new List<int>() { 1,3 };

    List<Person> SelectedEmployeeList = new List<Person>();

    var temp = eid.Select(i => 
                EmployeeList.ContainsKey(i) 
                ? EmployeeList[i]
                : null
            ).Where(i => i != null).ToList();

}

Upvotes: 1

Alex
Alex

Reputation: 23300

you could linq your way through mappings EDITED i missed a nesting level, he wants to query hashsets not the whole dictionary

public void DoStuff(IEnumerable<string> key, int iClassId)
{
    mappings.Where(i=>key.Contains(i.Key)).ToList().ForEach(obj=>
    {
        foreach (var classEntry in
             from c in obj.Value
             where c.StartsWith(iClassId + "(")
             select c)
        {
            DoStuffWithEntry(classEntry);
        }
}

changed key parameter and from c ... section.

you call it like this

string[] keys = new string[]{"key1", "key2", ... , "keyN"};
DoStuff(keys, 123);

this should work

Upvotes: 0

Pranay Rana
Pranay Rana

Reputation: 176946

You can make use something like this

var ids = {1, 2, 3};  
var query = from item in context.items             
where ids.Contains(item.id )             
select item; 

in your case

string[] keys = { "key1", "key2", ... }
 var query = from key in keys             
  where ids.Contains(keys  )             
   select key ; 

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1502835

It sounds like you want:

string[] keys = { "key1", "key2", ... }
var query = from key in keys
            from c in mappings[key]
            ...;

foreach (var entry in query)
{
    ...
}

(I would personally use a separate variable for the query just for readability - I'm not too keen on the declaration bit of a foreach loop getting huge.)

Upvotes: 4

Related Questions