【问题标题】:Split Array By Values In Sequence [duplicate]按顺序按值拆分数组[重复]
【发布时间】:2017-10-05 21:17:01
【问题描述】:

是否有一种简单的(linq?)方法可以根据完整的数字序列将int 数组拆分为新数组?例如给出这个伪代码:

[Fact]
public void ArraySpike()
{
   var source = new[] {1, 2, 3, 7, 8, 9, 12, 13, 24};

   var results = SplitArray(source);

    Assert.True(results[0] == new[] {1, 2, 3});
    Assert.True(results[1] == new[] {7, 8, 9}); 
    Assert.True(results[2] == new[] {12, 13}); 
    Assert.True(results[3] == new[] {24}); 
}

public int[][] SplitArray(int[] source)
{
    return source.???   
}

【问题讨论】:

  • 什么是组?每 5 位数? (1-5、6-10、11-15 等)?
  • @igor no,数字连续,所以 group1 = 1,2,3 group2 = 7,8,9 group3 = 12,13 group4 = 24
  • 啊,那只是巧合。
  • 不知道为什么投反对票(可能没有尝试?),我认为这个问题很有趣。
  • 可能,我有一个“丑陋”的尝试,但我猜那将是代码审查。

标签: c# arrays linq


【解决方案1】:

这可以与 linq 扩展 Aggregate 一起使用。我的播种不是很优雅很容易改变。 results 变量将包含数组数组,它​​们实际上是 List<T> 类型,因为这样它们可以很容易地在数组 [] 始终具有固定大小的函数中增长。

这也假定源已经有序且唯一,如果不是这种情况,请添加.OrderBy(x => x).Distinct()

var source = new[] { 1, 2, 3, 7, 8, 9, 12, 13, 24 };
var results = new List<List<int>>{new List<int>()};

var temp = source.Aggregate(results[0], (b, c) =>
{
    if (b.Count > 0 && b.Last() != c - 1)
    {
        b = new List<int>();
        results.Add(b);
    }
    b.Add(c);
    return b;
});

【讨论】:

    【解决方案2】:

    我从我的个人收藏中挖掘了这个扩展方法:

    public static IEnumerable<IEnumerable<T>> GroupConnected<T>(this IEnumerable<T> list, Func<T,T,bool> connectionCondition)
    {
        if (list == null)
        {
            yield break;
        }
        using (var enumerator = list.GetEnumerator())
        {
            T prev = default(T);
            var temp = new List<T>();
            while (enumerator.MoveNext())
            {
                T curr = enumerator.Current;
                {
                    if(!prev.Equals(default(T)) && !connectionCondition(prev, curr))
                    {
                        yield return temp;
                        temp = new List<T>();
                    }
                    temp.Add(curr);
                }
                prev = curr;
            }
            yield return temp;
        }
    }
    

    它从更一般的意义上解决了这个问题:将一个序列拆分为以某种方式“连接”的元素的子序列。它遍历序列并将每个元素收集到一个临时列表中,直到下一个项目没有“连接”。然后它返回临时列表并开始一个新列表。

    当你的数组元素有1的差异时,它们是连接的:

    var results = source.GroupConnected((a,b) => b - a == 1);
    

    【讨论】:

      猜你喜欢
      • 2021-12-30
      • 2019-03-20
      • 2014-08-06
      • 1970-01-01
      • 2019-04-05
      • 1970-01-01
      • 2012-07-06
      • 2016-04-02
      相关资源
      最近更新 更多