假设我有以下数组(我的序列都按升序排序,并包含正整数)
var mySequence = new [] {1, 2, 3, 7, 8, 9, 15, 16, 17};
Run Code Online (Sandbox Code Playgroud)
我想写一个linq查询来选择被视为一个组的系列中的连续数字.所以,在上面的例子中我会得到{[1,2,3],[7,8,9],[15,16,17]}.
我可以编写一个foreach()序列,遍历每个元素,看看序列在哪里跳跃并在那里产生一个组.但有没有LINQ唯一的方法呢?我可能能够将我的foreach()代码移动到一个新的扩展方法,所以我的代码仍然看起来像LINQy,但我想知道System.Linq中是否有任何可用的东西.
编辑:我创建了自己的扩展(如下所示),但Me.Name在他的答案中提出了一些非常聪明的东西.
internal class Sequence
{
public int Start { get; set; }
public int End { get; set; }
}
internal static class EnumerableMixins
{
public static IEnumerable<Sequence> GroupFragments(this IEnumerable<int> sequence)
{
if (sequence.Any())
{
var lastNumber = sequence.First();
var firstNumber = lastNumber;
foreach(var number in sequence.Skip(1))
{
if (Math.Abs(number - lastNumber) > 1)
{
yield return new Sequence() { Start = firstNumber, End = lastNumber };
firstNumber = lastNumber = number;
}
else
{
lastNumber = number;
}
}
yield return new Sequence() { Start = firstNumber, End = lastNumber };
}
}
}
Run Code Online (Sandbox Code Playgroud)
Me.*_*ame 10
找到这些岛屿的一个老技巧是减去索引和数值.结果将代表独特的群体.使用包含索引的select重载:
var mySequence = new [] {1, 2, 3, 7, 8, 9, 15, 16, 17};
var groups = mySequence
.Select((val,ind) => new{val, group = val - ind})
.GroupBy(v=>v.group, v=>v.val)
.Select(v=> v.ToList()).ToList();
Run Code Online (Sandbox Code Playgroud)
(在这里使用ToList,但当然如果首选数组则可以使用ToArray)
| 归档时间: |
|
| 查看次数: |
186 次 |
| 最近记录: |