Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Group and Sum With Select Many C#?

I have an incoming array with a count per row and a string which represents one or more key's split by underscore.

for each key I'd like to group and sum the total where if the key appears in a row with a total of 5, each item split by the underscore have their total increased by 5.

I was just wondering how this would be represented in linq...

 class Owl
    {
        public int SpeciesCount { get; set; }
        public string BandIdentifier { get; set; }
    }

public class GoOwl
{
    public GoOwl(Owl[] owls)
    {
       //just making a list of test data to illustrate what would be coming in on the array
        var owlList = new List<Owl>();
        owlList.Add(new Owl { SpeciesCount = 2, BandIdentifier = "OWL1" });
        owlList.Add(new Owl { SpeciesCount = 1, BandIdentifier = "OWL1_OWL2_OWL3" });
        owlList.Add(new Owl { SpeciesCount = 2, BandIdentifier = "OWL3" });
        owlList.Add(new Owl { SpeciesCount = 5, BandIdentifier = "OWL2_OWL3" });

        //i'd ideally like to have something like a row for each band identifier split on underscore plus a total species count..
        //where you'd sum the species count for each underscored item and group


    }
}

the following would be the desired output as single Owl objects

["OWL1", 3]
["OWL2", 6]
["OWL3", 8]

I'm still not quite getting SelectMany..

Cheers

like image 524
TheLearningDev Avatar asked Dec 20 '22 06:12

TheLearningDev


1 Answers

In fluent sytnax:

//For each 'owlItem' in the owlList, select an anonymous objects for each key in the BandIdentifier string, keeping track of the associated SpeciesCount
//Since each call to Split('_').Select(...) produces an IEnumerable of those anonymous objects, use SelectMany to flatten the IEnumerable to IEnumerables 
owlList.SelectMany(owlItem => owlItem.BandIdentifier.Split('_')
                .Select(key => new { OwlKey = key, owlItem.SpeciesCount }))
            //Group together those anonymous objects if they share the same key
            .GroupBy(info => info.OwlKey)
            //For each of the groups, sum together all the associated SpeciesCounts
            .Select(group => new { group.Key, SpeciesCount = group.Sum(info => info.SpeciesCount) })'
like image 154
Ben Reich Avatar answered Jan 05 '23 07:01

Ben Reich