Home > database >  Group by custom condition
Group by custom condition

Time:12-27

Given:

var arr = new int[] {
    10, 20, 30,
    10, 20, 30, 40, 50,
    10, 20
};

Wanted:

var group1 = new int [] { 10, 20, 30 };
var group2 = new int [] { 10, 20, 30, 40, 50 };
var group3 = new int [] { 10, 20 };

Need to group by value => when next element's value is lower than the previous one, create new group. Would appreciate LINQ-based solution.

CodePudding user response:

Technically, you can put something like this:

int prior = int.MinValue;
int group = 0;

var result = arr
  .GroupBy(item => { 
     if (item < prior) 
       group  = 1;

     prior = item;

     return group;  
   });

but if you don't insist on IGrouping<int, int> and agree with IEnumerable<int[]>, foreach looks better (let's generalize the solution):

public static partial class EnumerableExtensions { 
  public static IEnumerable<T[]> GroupByAsc<T>(this IEnumerable<T> source, 
                                                    Comparer<T> comparer = null) {
    if (source is null)
      throw new ArgumentNullException(nameof(source));

    if ((comparer ??= Comparer<T>.Default) is null)
      throw new ArgumentNullException(nameof(comparer), 
        $"Type {typeof(T).Name} doesn't have default comparer");

    List<T> list = new List<T>();

    foreach (var item in source) 
      if (list.Count > 0 && comparer.Compare(list[list.Count - 1], item) <= 0)
        list.Add(item);
      else {
        if (list.Count > 0)
          yield return list.ToArray();

        list.Clear();

        list.Add(item);
      }
    
    if (list.Count > 0)
      yield return list.ToArray();
  }
}

Usage:

var result = arr
  .GroupByAsc();

Fiddle

CodePudding user response:

try this

void Main()
{
    
   var arrList= GroupCollection(arr);
    
    if (arrList.Count() < 3) Console.WriteLine("Error! Array is too short");
    
    var group1=arrList[0].ToArray();
    var group2=arrList[1].ToArray();
    var group3=arrList[2].ToArray();
     
}
public static List<List<int>>  GroupCollection(int[] arr)
{
    List<List<int>> arrList = new List<List<int>>();

    var prevItem = arr[0];
    var currList = new List<int>();

    foreach (var item in arr)
    {
        if (prevItem > item)
        {
            arrList.Add(currList);
            currList = new List<int>();
        }
        currList.Add(item);
        prevItem = item;
    }
    arrList.Add(currList);
    return arrList;
}
  • Related