为了账号安全,请及时绑定邮箱和手机立即绑定

LINQ分区列表分为8个成员的列表

/ 猿问

LINQ分区列表分为8个成员的列表

慕娘9325324 2019-11-19 10:23:08

一个人如何使用LINQ来获取一个列表并将其分解为一个列表列表,从而在每第8个条目上对原始列表进行分区?

我想像这样的事情会涉及“跳过”和/或“接听”,但是我对LINQ还是很陌生。

编辑:使用C#/ .Net 3.5

Edit2:该问题的措词与其他“重复”问题不同。尽管问题相似,但该问题的答案更好:“接受的”答案非常可靠(带有yield陈述),以及乔恩·斯凯特的建议使用MoreLinq(“其他”问题中不建议)。有时重复是好的,因为重复会迫使您重新检查问题。


查看完整描述

3 回答

?
慕田峪9158850

使用以下扩展方法将输入分成子集


public static class IEnumerableExtensions

{

    public static IEnumerable<List<T>> InSetsOf<T>(this IEnumerable<T> source, int max)

    {

        List<T> toReturn = new List<T>(max);

        foreach(var item in source)

        {

                toReturn.Add(item);

                if (toReturn.Count == max)

                {

                        yield return toReturn;

                        toReturn = new List<T>(max);

                }

        }

        if (toReturn.Any())

        {

                yield return toReturn;

        }

    }

}


查看完整回答
反对 回复 2019-11-19
?
德玛西亚99

在MoreLINQ中,我们有这样一种方法作为Batch方法:


// As IEnumerable<IEnumerable<T>>

var items = list.Batch(8);

要么


// As IEnumerable<List<T>>

var items = list.Batch(8, seq => seq.ToList());


查看完整回答
反对 回复 2019-11-19
?
慕姐8265434

您最好使用MoreLinq之类的库,但如果确实需要使用“ plain LINQ”来执行此操作,则可以使用GroupBy:


var sequence = new[] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};


var result = sequence.Select((x, i) => new {Group = i/8, Value = x})

                     .GroupBy(item => item.Group, g => g.Value)

                     .Select(g => g.Where(x => true));


// result is: { {1,2,3,4,5,6,7,8}, {9,10,11,12,13,14,15,16} }

基本上,我们使用的版本为Select()要消耗的值提供索引,我们将索引除以8以标识每个值所属的组。然后,通过此分组键对序列进行分组。最后一个Select将IGrouping<>下降减少到,IEnumerable<IEnumerable<T>>(由于IGrouping是,因此不是严格必需的IEnumerable)。


通过8在示例中考虑常量并将其替换为指定的参数,将其转变为可重用的方法很容易。它不一定是最优雅的解决方案,也不再是一种懒惰的流式解决方案……但是它确实可以工作。


您也可以使用迭代器块(yield return)编写自己的扩展方法,这样可以为您提供更好的性能和更少的内存GroupBy。这就是Batch()MoreLinq 的方法进行IIRC的方式。


查看完整回答
反对 回复 2019-11-19

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信