我有一个int值的排序列表,我想组成相邻的值。下一个值为nextvalue> = prevValue + 1的值是邻居。
例如: 列表:
{1,2,3,5,6,8,9,10}
小组将:
{1,2,3}
{5,6}
{8,9,10}
可以使用linq完成吗?
这可以很容易地在没有linq的情况下完成 - 通过迭代列表,但我想知道linq是否有解决方案。
答案 0 :(得分:1)
如果您必须使用Linq,则可以考虑使用Aggregate
方法。
x.Aggregate(new List<List<int>> { new List<int>() }, (soFar, next) => {
if (soFar.Last().Contains(next - 1)) {
soFar.Last().Add(next);
} else {
soFar.Add(new List<int> { next });
}
return soFar;
});
答案 1 :(得分:1)
这对我有用:
private static void GroupToNeighboursTest()
{
var numbers = new List<int> { 1, 2, 3, 5, 6, 8, 9, 10 };
var neighbours = numbers
.Zip(numbers.Skip(1), Tuple.Create)
.Aggregate(new List<List<int>> { new List<int> { numbers.First() } }, (result, i) =>
{
if (i.Item1 == i.Item2 - 1)
{
result.Last().Add(i.Item2);
}
else
{
result.Add(new List<int> { });
result.Last().Add(i.Item2);
}
return result;
});
}
答案 2 :(得分:1)
这对我有用:
var result =
items
.Skip(1)
.Aggregate(
new [] { items.Take(1).ToList() }.ToList(),
(acc, item) =>
{
if (acc.Last().Last() == item - 1)
{
acc.Last().Add(item);
}
else
{
acc.Add(new [] { item }.ToList());
}
return acc;
});
我得到了这个结果:
作为旁注,我喜欢养成建立像new [] { item }.ToList()
这样的列表的习惯,因为它允许构建匿名类型的列表。在许多LINQ查询中非常有用。
答案 3 :(得分:0)
我只有一个非linq解决方案(如果我已正确理解问题)。希望它有所帮助。
void Main()
{
var list = new List<int>{1,2,3,5,6,8,9,10};
GetData(list).Dump();
}
public IEnumerable<List<int>> GetData(IEnumerable<int> data)
{
int prev = 0;
var g = new List<int>();
foreach (var item in data)
{
if(item - prev > 1 && g.Count > 0)
{
yield return g;
g = new List<int>();
}
g.Add(item);
prev = item;
}
yield return g;
}