【问题标题】:Group by custom condition [closed]按自定义条件分组[关闭]
【发布时间】:2021-12-26 16:54:02
【问题描述】:

给定:

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 的解决方案。

【问题讨论】:

标签: c# linq grouping


【解决方案1】:

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

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

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

     prior = item;

     return group;  
   });

但如果你不坚持IGrouping&lt;int, int&gt; 并同意IEnumerable&lt;int[]&gt;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

【讨论】:

    【解决方案2】:

    试试这个

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多