c# - how to count continuous values in a list with linq -
i've list this:
var query = enumerable.range(0, 999).select((n, index) => { if (index <= 333 || index >=777) return 0; else if (index <= 666) return 1; else return 2; });
so, can find how indexes have same value continuously? example;
query[0]=query[1]=query[2]=query[3]... = 0, query[334] = 1, query[777]=query[778]... = 0.
first 334 indexes have 0, first answer 333. last 223 indexes have 0, second answer 223..
how can find these , indexes?
thanks in advance.
you can create extension consecutive grouping of items key:
public static ienumerable<igrouping<tkey, t>> groupconsecutive<t, tkey>( ienumerable<t> source, func<t, tkey> keyselector) { using (var iterator = source.getenumerator()) { if (!iterator.movenext()) yield break; else { list<t> list = new list<t>(); var comparer = comparer<tkey>.default; list.add(iterator.current); tkey groupkey = keyselector(iterator.current); while (iterator.movenext()) { var key = keyselector(iterator.current); if (!list.any() || comparer.compare(groupkey, key) == 0) { list.add(iterator.current); continue; } yield return new group<tkey, t>(groupkey, list); list = new list<t> { iterator.current }; groupkey = key; } if (list.any()) yield return new group<tkey, t>(groupkey, list); } } }
of course can return ienumerable<ilist<t>>
little different concept of group, want have, because want know value used group sequence of items. unfortunately there no public implementation of igrouping<tkey, telement>
interface, , should create our own:
public class group<tkey, telement> : igrouping<tkey, telement> { private tkey _key; private ienumerable<telement> _group; public group(tkey key, ienumerable<telement> group) { _key = key; _group = group; } public tkey key { { return _key; } } public ienumerator<telement> getenumerator() { return _group.getenumerator(); } ienumerator ienumerable.getenumerator() { return getenumerator(); } }
now usage simple:
var groups = query.groupconsecutive(i => i) // produces groups .select(g => new { g.key, count = g.count() }); // projection
result:
[ { key: 0, count: 334 }, { key: 1, count: 333 }, { key: 2, count: 110 }, { key: 0, count: 222 } ]
Comments
Post a Comment