After your updates: var query = arrangements . GroupBy(a => a.Aspect. Name) .
Select(g => new Arrangement { Steps = ga. SelectMany(a => a. Steps) .
GroupBy(s => s. Rank) . Select(gs => gs.Last()), Aspect = ga.First().
Aspect }) This will create output as in your example Now, how to merge it with your current aggregation method? As to my understanging, you want to create one big layout from all current layout contents (including arrangements, pages, etc)? You don't need aggregate at all, just split it into 3 LINQ queries: get all arrangements object from all layouts flattening with SelectMany var arrangements = source.
SelectMany(s => s. Arrangements); // and filter them var filteredArrangements = // enter larger query from above here // repeat the same for Apertures and Pages ... // and return single object return new Layouts. Template { Apertures = filteredApertures, Arrangements = filteredArrangements, Pages = filteredPages }.
After your updates: var query = arrangements . GroupBy(a => a.Aspect. Name) .
Select(g => new Arrangement { Steps = ga. SelectMany(a => a. Steps) .
GroupBy(s => s. Rank) . Select(gs => gs.Last()), Aspect = ga.First().
Aspect }); This will create output as in your example. Now, how to merge it with your current aggregation method? As to my understanging, you want to create one big layout from all current layout contents (including arrangements, pages, etc)?
You don't need aggregate at all, just split it into 3 LINQ queries: // get all arrangements object from all layouts flattening with SelectMany var arrangements = source. SelectMany(s => s. Arrangements); // and filter them var filteredArrangements = // enter larger query from above here // repeat the same for Apertures and Pages ... // and return single object return new Layouts.
Template { Apertures = filteredApertures, Arrangements = filteredArrangements, Pages = filteredPages }.
Fixed my example, sorry for the typo. – Ciel Apr 25 at 19:39 Alright, I'm sorry for the bad example. I have updated my code to be much more clear.
– Ciel Apr 25 at 20:53 @Ciel: no worries mate, I've updated my answer - fill it up and check if you can go without Aggregate at all. – jimmy_keen Apr 25 at 21:29 Hrnm. I'm not entirely sure.
I cannot get your example to work, it is rejecting it claiming that the anonymous type cannot be assigned to the new Template. Arrangements property. – Ciel Apr 25 at 21:36 Ok, solve that.
I wasn't converting to a List. Why are you using .Last()? This confuses me a little bit.
Doesn't this mean that anything in the 'inherited' arrangements will be lost? – Ciel Apr 25 at 21:39.
If there's no correlation between steps and apertures you can do this: var result = new Arrangement{ Steps = list. SelectMany(arrangement => arrangment. Steps) .
GroupBy(step => step. Rank) . Select(l => l.Last()) .
OrderBy(step => step. Rank) .ToList()), } If there is you'll need to combine the two somehow. If steps index into apertures then you can use something similar.
This may be what I am trying to do, yes. When I tried GroupBy I continued to get awkward errors stating that it was no longer an IEnumerable. I already have an aggregation going over the IEnumerable, what I hope to do is keep all of the logic contained in that one place instead of breaking it up all over the place.
– Ciel Apr 25 at 19:41 What is the current aggregation you are doing? – Talljoe Apr 25 at 19:44 I have updated my post with an example of what I already have. – Ciel Apr 25 at 20:41 Your solution works if I have only one Arrangement, but as you can see I have multiple.
Each Arrangement has a Property called Aspect which is the similar object to group by. I'll update the sample code to reflect this, it didn't occur to me. I want to get all Arrangements that share the same Aspect.Name, and get a complete list of Steps, overwriting lower level Steps where higher level Arrangements have the same Rank with a different Required value.
– Ciel Apr 25 at 20:49 1 My example will take a list of arrangements and give you one arrangement. If you want to group your arrangements by Name before performing this step you can use that as input to this step. – Talljoe Apr 25 at 21:33.
I assume this isn't the complete solution that you want: private static Arrangement Accumulate(IEnumerable arrangements) { var stepsByRank = new Dictionary(); foreach (var arrn in arrangements) foreach (var step in arrn. Steps) stepsByRankstep. Rank = step; return new Arrangement { Steps = stepsByRank.Values.ToArray() }; } What's missing from this?
How else do you want to "aggregate" the arrangements and steps? (edit: after reading your comment, maybe this actually is what you want. ).
I cannot use Dictionaries, unfortunately. – Ciel Apr 25 at 19:37 1 Er...okay. Well, conceptually this is what you're going to be doing -- the other one-liner answers posted here use GroupBy to put the steps in a hash table, just like this does, but phrased differently.
If your religion prohibits you from using hash tables on Mondays and Wednesdays, I guess you can pick an alternative kosher data structure like a tree to play the same role. – mquander Apr 25 at 19:39 I misread part of your answer, sorry. I meant that I cannot return the data as a dictionary because it has to go back to a database, and working with dictionaries and ORMs has proven more frustrating than it is worth.
I will try this when I get back to my work machine, but I don't think it will run inline with the rest of the aggregate method... – Ciel Apr 25 at 19:43 Ok. Sorry about that. When I made my post, I got called away, and I kept reading via my phone.
When I read your first answer I misinterpreted it simply due to how much I could see on the screen. Yes, all of the solutions will inevitably create a dictionary, so this isn't an issue. I thought you were trying to make it return a dictionary.
– Ciel Apr 25 at 20:46 I have updated my code to be more clear about my intentions. I am very sorry it wasn't straightforward enough to begin with. – Ciel Apr 25 at 21:10.
Using a semi-complex structure, I am trying to 'combine' several objects into one using the Linq Aggregate method (though if there is a better way, I am open to ideas). Here is my basic class design. Basically, I am trying to aggregate the entire hierarchy of an IEnumerable and keep everything on the base level, but where things can appropriately overwrite, I want to overwrite them.
I want to get all Arrangements that share the same Aspect.Name, and get a complete list of Steps, overwriting lower level Steps where higher level Arrangements have the same Rank with a different Required value. I have attempted to use Distinct and Aggregate and it just isn't getting me anywhere. I keep ending up not getting one list or the other.
Can anyone help with this?
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.