这件事完全把我搞糊涂了。
假设我们有一个整数列表
var list = new List {
1,
2,
3,
5,
6,
7,
9,
10
};我怎么能把这个分组,这里是1,3,5,7,9-10,这个组被除以,下一个整数丢失了?
发布于 2019-08-31 17:07:11
看看这个有用不管用。没有循环,只有linq
List<int> list = new List<int> { 1, 2, 3, 5, 6, 7, 9, 10};
List<int> splitIndex = list.Skip(1).Select((x,i) => new { x = x, i = i}).Where(x => list[x.i] + 1 != x.x).Select(x => x.i).ToList();
//add last index
splitIndex.Add(list.Count - 1);
var results = splitIndex.Select((x,i) => (i == 0) ? list.Take(x + 1).ToList() : list.Skip(splitIndex[i - 1] + 1).Take(splitIndex[i] - splitIndex[i - 1]).ToList()).ToList(); 发布于 2019-08-31 16:46:44
您不会用简单的LINQ实现它,但是您可以编写自己的扩展方法来处理这种分组。
您必须将其放置在静态类中,并将其称为普通LINQ。
public static class LinqExtensions
{
public static IEnumerable<IEnumerable<int>> GroupSequential (
this IEnumerable<int> source)
{
var previous = source.First();
var list = new List<int>() { previous };
foreach (var item in source.Skip(1))
{
if (item - previous != 1)
{
yield return list;
list = new List<int>();
}
list.Add(item);
previous = item;
}
yield return list;
}
}像list.GroupSequential()一样叫它
我觉得这个应该能满足你的需要。
发布于 2019-08-31 17:21:29
我同意@Arion的观点,用一个可读的LINQ方法链可能是不可能的。@jdweng证明我错了:-)
我想提供我的替代解决方案。它是一种扩展方法,它使用自定义的间隔类型。
范围:
public struct Interval
{
public Interval(int from, int to)
{
From = from;
To = to;
}
public int From { get; }
public int To { get; }
public IEnumerable<int> Members() => Enumerable.Range(From, To - From + 1);
}要获取Range中的数字,可以使用Numbers()函数。数字是懒洋洋地生成的,因此,除非您需要它们,否则可以节省空间。
分机:
public static class EnumerableExtensions
{
public static IEnumerable<Interval> GetIntervals(this IEnumerable<int> numbers)
{
var array = numbers.OrderBy(x => x).ToArray();
var fromIndex = 0;
var toIndex = fromIndex;
for (var i = 1; i < array.Length; i++)
{
var current = array[i];
if (current == array[toIndex] + 1)
{
toIndex++;
}
else if (fromIndex != toIndex)
{
yield return new Interval(array[fromIndex], array[toIndex]);
fromIndex = i;
toIndex = fromIndex;
}
}
if (toIndex != fromIndex)
{
yield return new Interval(array[fromIndex], array[toIndex]);
}
}
}用法:
public void Demo()
{
var list = new List<int> {1, 2, 3, 5, 6, 7, 9, 10};
// 1-3, 5-7, 9-10, lazily generated
var intervals = list.GetIntervals();
foreach (var interval in intervals)
{
// [1, 2, 3], then [5, 6, 7], then [9, 10], lazily generated
var members = interval.Members();
foreach (var numberInRange in members)
{
// do something with numberInRange
}
}
}https://stackoverflow.com/questions/57739843
复制相似问题