Tuesday 15 April 2014

c# - Generate IGrouping yourself -



c# - Generate IGrouping yourself -

i have list of instances of own class "vertrag" ("contract") , need grouping on them.

a simple groupby need: grouping lastly 4 fields, result ienumerable<igrouping<...,vertrag>>. can work result type, easy plenty iterate on.at spot marked ... nil given type definition. seems anonymous type?

now got farther request: create sure there max. 3 elements in each group. start new groups (still same key!) until allocated. found solution in stackoverflow, linq bit more complex working fine. homecoming type more complex. i'd prefer transform complex construction simple igrouping-form works existing code.

i got working, or @ to the lowest degree simplified downwards version easy utilize simple groupby one, yet not same. there way create igrouping anonymous type there no need alter code next original grouping?

the key come identical more once, opposite of groupby means do. not sure if hand-crafted igrouping allow exist.

this working linqpad illustration (with type definition):

void main() { list<vertrag> verträge = new list<vertrag>(); verträge.add(new vertrag("a1","b1","c","d","e")); verträge.add(new vertrag("a2","b1","c","d","e")); verträge.add(new vertrag("a3","b1","c","d","e")); verträge.add(new vertrag("a4","b1","c","d","e")); verträge.add(new vertrag("a5","b1","c","d","e")); verträge.add(new vertrag("a6","b1","c","d","e")); verträge.add(new vertrag("a7","b1","c","d","e")); verträge.add(new vertrag("a1","b2","c","d","e")); verträge.add(new vertrag("a2","b2","c","d","e")); verträge.add(new vertrag("a3","b2","c","d","e")); verträge.add(new vertrag("a4","b2","c","d","e")); // easy first grouping var verträgegruppiert = verträge .groupby(v => new { v.beginn, v.ende, v.vorlage, v.ware }); verträgegruppiert.dump(); // far more complex grouping var maxingroup = 3; var verträgegruppiertmax = verträge .groupby(v => new {v.beginn, v.ende, v.vorlage, v.ware}) .select(g => new { key = g.key, teile = g.select((v,i) => new {value = v, index = i}) .groupby(item => item.index / maxingroup) }); verträgegruppiertmax.dump(); // transform simpler style // selectmany used instead select, see comment in question var vereinfacht = verträgegruppiertmax .selectmany(vgm => vgm.teile .select(t => new { vgm.key, = t.select(x => x.value.id) })); vereinfacht.dump(); } public class vertrag { public vertrag( // constructor string id, string beginn, string ende, string vorlage, string ware) { id = id; beginn = beginn; ende = ende; vorlage = vorlage; ware = ware; } // fields public string id { get; private set; } public string beginn { get; private set; } public string ende { get; private set; } public string vorlage { get; private set; } public string ware { get; private set; } }

just implement igrouping own desired behaviour. create code much simpler.

the "application":

var elements = new list<tuple<string, string, string, string>>(); elements.add(tuple.create("a", "one", "a1", "banana")); elements.add(tuple.create("a", "two", "b3", "orange")); elements.add(tuple.create("a", "three", "c5", "kiwi")); elements.add(tuple.create("a", "four", "d7", "coconut")); elements.add(tuple.create("a", "five", "e9", "maracuja")); elements.add(tuple.create("b", "one", "a1", "banana")); elements.add(tuple.create("b", "two", "b3", "orange")); elements.add(tuple.create("b", "three", "c5", "kiwi")); elements.add(tuple.create("b", "four", "d7", "coconut")); elements.add(tuple.create("b", "five", "e9", "maracuja")); var groups = elements.groupby(element => element.item1); var cuttedgroups = groups.select(group => cuttedgroup.create(group, 3)); foreach (var grouping in cuttedgroups) { foreach (var item in group) { console.writeline(item); } console.writeline(); }

the implementation of cuttedgroup:

public static class cuttedgroup { public static igrouping<tkey, telement> create<tkey, telement>(igrouping<tkey, telement> source, int maximumelements) { homecoming new cuttedgroup<tkey, telement>(source, maximumelements); } } public class cuttedgroup<tkey, telement> : igrouping<tkey, telement> { private igrouping<tkey, telement> _source; private int _maximumelements; public cuttedgroup(igrouping<tkey, telement> source, int maximumelements) { // parameter check omitted... _source = source; _maximumelements = maximumelements; } public tkey key { { homecoming _source.key; } } public ienumerator<telement> getenumerator() { homecoming _source.take(_maximumelements).getenumerator(); } system.collections.ienumerator system.collections.ienumerable.getenumerator() { homecoming getenumerator(); } }

c# linq igrouping

No comments:

Post a Comment