Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 使用linq对相邻值进行分组_.net_Linq_Group By_Aggregate - Fatal编程技术网

.net 使用linq对相邻值进行分组

.net 使用linq对相邻值进行分组,.net,linq,group-by,aggregate,.net,Linq,Group By,Aggregate,我有一个整型值的排序列表,我想让组与值相邻。下一个值为nextvalue>=prevValue+1的值是相邻值 例如: 名单: 小组将包括: {1,2,3} {5,6} {8,9,10} 这可以用linq实现吗 这可以很容易地在没有linq的情况下完成-通过迭代列表,但我想知道linq是否对此有解决方案。我只有一个非linq解决方案(如果我正确理解了问题)。希望能有帮助 void Main() { var list = new List<int>{1,2,3,5,6,8,9

我有一个整型值的排序列表,我想让组与值相邻。下一个值为nextvalue>=prevValue+1的值是相邻值

例如: 名单:

小组将包括:

{1,2,3}
{5,6}
{8,9,10}
这可以用linq实现吗


这可以很容易地在没有linq的情况下完成-通过迭代列表,但我想知道linq是否对此有解决方案。

我只有一个非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;
}
void Main()
{
var list=新列表{1,2,3,5,6,8,9,10};
GetData(list.Dump();
}
公共IEnumerable GetData(IEnumerable数据)
{
int prev=0;
var g=新列表();
foreach(数据中的var项)
{
如果(项目-上一个>1和&g.计数>0)
{
收益率g;
g=新列表();
}
g、 增加(项目);
prev=项目;
}
收益率g;
}

< /代码> 如果您必须使用LINQ,可以考虑<代码>聚合< /代码>方法。< /P>
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; 
});
x.Aggregate(新列表{new List()},(soFar,next)=>{
if(soFar.Last().Contains(next-1)){
soFar.Last().Add(下一步);
}否则{
添加(新列表{next});
}
返回索法尔;
});
这对我很有用:

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;
        });
}
private static void GroupToNeighboursTest()
{
变量编号=新列表{1,2,3,5,6,8,9,10};
var=数字
.Zip(number.Skip(1),Tuple.Create)
.Aggregate(新列表{new List{numbers.First()}},(结果,i)=>
{
如果(i.Item1==i.Item2-1)
{
result.Last().Add(i.Item2);
}
其他的
{
结果.添加(新列表{});
result.Last().Add(i.Item2);
}
返回结果;
});
}
这对我来说很有用:

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查询中非常有用。

LINQ是要求吗?是的,LINQ是要求。您确定条件正确吗?如果
nextvalue>=prevValue+1
则3和5是邻居:prevVal=3,nextVal=5->prevVal+1=4->5>=4为真,因此prevVal=3和nextVal=5是邻居。它不应该是:
nextvalue==prevValue+1
包含
是一个O(n)操作。另外,这似乎在开始时返回了一个额外的空组。我认为,根据我对问题的理解,您可以将
.Contains(…)
行更改为
if(soFar.Last().Last()==next-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;
            });