Quick post: an extension method to group consecutive integers:
/// <summary> /// Groups consecutive integers. Requires asc-ordered list /// </summary> /// <param name="list">ASC-ordered list of integers</param> /// <returns></returns> public static IEnumerable<IEnumerable<int>> GroupConsecutive(this IEnumerable<int> list) { var group = new List<int>(); foreach (var i in list) { if (group.Count == 0 || i - group[group.Count - 1] <= 1) group.Add(i); else { yield return group; group = new List<int> {i}; } } yield return group; }
Sample usage:
var groups = new[] {1, 2, 4, 5, 6, 9}.GroupConsecutive(); foreach (var g in groups) Console.WriteLine("group: {0}", string.Join(",", g.Select(x => x.ToString()).ToArray()));
which prints out:
group: 1,2 group: 4,5,6 group: 9
Very cool :)
ReplyDeleteliked it, thanks
ReplyDeleteHandy routine; thanks. I added the following to the beginning of the method to better support an empty input list. Otherwise, an empty group is returned.
ReplyDeleteif (list.Count() == 0)
yield break;
F# version :)
ReplyDeletelet groupConsecutive xs =
List.foldBack (fun x acc ->
match acc, x with
| [], _ -> [[x]]
| (h :: t) :: rest, x when h - x <= 1 -> (x :: h :: t) :: rest
| acc, x -> [x] :: acc) xs []
So how can we group only 4,5,6 and others not?
ReplyDeleteQuestion is this groups every element even if they are alone, but is there a way to prevent creating single groups and create a consecutive group if group count is min 3?? (Like 4,5,6 but not 1,2 or 9)
Any idea?