Giacomo
Giacomo

Reputation: 279

How to choose certain values from ICollection to IDictionary, using LINQ

I have IDictionary<int,bool?> where int - id, bool? - state (true,false,null) So i need to filter ICollection of objects, where i should compare internal id with id of my IDictionary and if IDs are the same and the state is true - i should select this element (using LINQ)

I tried: incomeCollection.Values.Select(x=>x.InternalId.Equals(dataFromDictionary.Keys.Any)).Select(h=> new Item){Item = h.Name}

but it does not works. I need to check all collection and select elements, which satisfy the condition above using LINQ. How can i do this?

Upvotes: 0

Views: 627

Answers (3)

Anu Viswan
Anu Viswan

Reputation: 18153

You can use Any()

var result = list.Where(x=>dictionary.Keys.Any(c=>c.Equals(x.Id))  && x.State.HasValue && x.State==true).Select(x=>x);

You can also use Join.

var result = list.Join(dictionary,
                        l=>l.Id, 
                        d=>d.Key,(l,d)=>l)
                  .Where(x=>x.State.HasValue && x.State==true).Select(x=>x);

For example,

var dictionary = new Dictionary<int,bool?>
{
        [1] = true,
        [3] = true,
        [35] = false
};
var list = new List<Person>
{
  new Person{Name="Jia", Id=1,State=false},
  new Person{Name="Aami", Id=3,State=true},
  new Person{Name="Anu", Id=35,State=null},
};

Output

Aami 3 True 

Upvotes: 0

Klaus G&#252;tter
Klaus G&#252;tter

Reputation: 12007

The dictionary has a handy TryGetValue method allowing to look up an entry quickly.

class Income
{
    public int InternalId { get; set; }
    public string Name { get; set; }
}

var dictionary = new Dictionary<int,bool?>
{
    {1, false},
    {2, true},
    {3, null},
};

var incomeCollection = new List<Income>
{
    new Income { InternalId = 1, Name = "A" },
    new Income { InternalId = 2, Name = "B" },
    new Income { InternalId = 3, Name = "C" },
    new Income { InternalId = 4, Name = "D" },
};

var result = incomeCollection.Where(x =>
    dictionary.TryGetValue(x.InternalId, out var status) && status == true)
    .Select(h=> new {Item = h.Name});

This is better than your first approach using dataFromDictionary.Keys.Any which does not take advantage of the Dictionary feature of quick lookup.

Upvotes: 3

Manoj Choudhari
Manoj Choudhari

Reputation: 5634

ToDictionary method can be used as shown in the below example.

In order to select only few values from ICollection you can use where clause.

List<Package> packages =
        new List<Package>
            { new Package { Company = "Coho Vineyard", Weight = 25.2, TrackingNumber = 89453312L },
              new Package { Company = "Lucerne Publishing", Weight = 18.7, TrackingNumber = 89112755L },
              new Package { Company = "Wingtip Toys", Weight = 6.0, TrackingNumber = 299456122L },
              new Package { Company = "Adventure Works", Weight = 33.8, TrackingNumber = 4665518773L } };

    // Create a Dictionary of Package objects, 
    // using TrackingNumber as the key.
    Dictionary<long, Package> dictionary =
        packages.ToDictionary(p => p.TrackingNumber);

    foreach (KeyValuePair<long, Package> kvp in dictionary)
    {
        Console.WriteLine(
            "Key {0}: {1}, {2} pounds",
            kvp.Key,
            kvp.Value.Company,
            kvp.Value.Weight);
    }

Upvotes: 0

Related Questions