按自定义条件分组

Group by custom condition

鉴于:

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

求职:

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

需要按值分组=>当下一个元素的值低于前一个元素时,创建新组。将不胜感激基于 LINQ 的解决方案。

从技术上讲,你可以这样写:

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

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

     prior = item;

     return group;  
   });

但如果你不坚持IGrouping<int, int>并同意IEnumerable<int[]>foreach看起来更好(让我们概括解决方案) :

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();
  }
}

用法:

var result = arr
  .GroupByAsc();

Fiddle

试试这个

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

扩展

public static class Util
{
    public static IEnumerable<IEnumerable<T>> GroupCollection<T>(this IEnumerable<T> arr) where T:IComparable
    {
        var  arrList = new List<List<T>>();

        var prevItem = arr.First();
        var currList = new List<T>();

        foreach (var item in arr)
        {
            if (item.CompareTo(prevItem) < 0)
            {
                arrList.Add(currList);
                currList = new List<T>();
            }
            currList.Add(item);
            prevItem = item;
        }
        arrList.Add(currList);
        return arrList;
    }
}