Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq expression. Help mimize code

Tags:

c#

linq

Please, help minimize the following code: There is a class with dictionary property:

class Foo
{
    public int Field { get; set; }
    public Dictionary<int, bool> dic { get; set; }
}

And a list of Foo instances. I want to get united dictionary from all class instances like that:

...

var items = new List<Foo>
    {
        new Foo {Field = 1, Dic = new Dictionary<int, bool> {{1, true}, {2, false}}},
        new Foo {Field = 2, Dic = new Dictionary<int, bool> {{3, true}, {2, false}}}
    };
    var result = new Dictionary<int, bool>();

    foreach (var dics in items.Select(x => x.Dic))
        foreach (var pair in dics)
            if (!result.ContainsKey(pair.Key))
                result.Add(pair.Key, pair.Value);

    // testing output 
    foreach (var pair in result)
        Console.WriteLine("{0}, {1}", pair.Key, pair.Value);

Is it possible to do this with pure LINQ approach? Thank you in advance!

like image 223
Andrew Florko Avatar asked Dec 01 '25 06:12

Andrew Florko


2 Answers

You can use SelectMany to grab and flatten the inner dictionary elements:

var result = items.SelectMany(f => f.Dic)
                  .GroupBy(pair => pair.Key)
                  .ToDictionary(g => g.Key, g => g.First().Value);

edit: If you're feeling brave, this can be improved even further by picking up the DistinctBy method from Jon Skeet's morelinq project. Essentially, the GroupBy step is actually overkill, since all we really want is the first value for each key. If we select only the pairs with distinct keys, we can avoid the grouping and subsequent First call, like so:

var result = items.SelectMany(f => f.Dic)
                  .DistinctBy(pair => pair.Key)
                  .ToDictionary(pair => pair.Key, pair => pair.Value);
like image 65
tzaman Avatar answered Dec 02 '25 21:12

tzaman


var result =
    (from item in items
     from pair in item.Dic
     group pair by pair.Key
     ).ToDictionary(g => g.Key, g => g.First().Value);
like image 41
Quartermeister Avatar answered Dec 02 '25 19:12

Quartermeister



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!