使用 linq 分解列表;分成很多列表 n 长度?

发布于 2024-10-20 17:57:17 字数 466 浏览 1 评论 0 原文

可能的重复:
如何拆分 IEnumerable分成 IEnumerable

我有一个列表,我想将其分成 10 组。

如果我有一个

List<Person> allPendingPersons 

长度为 m 的对象。

LINQ 中是否有一种优雅的方法可以将 allPendingPersons 分解为一个或多个最多包含 10 名人员的 List 对象?

Possible Duplicate:
How can I split an IEnumerable<String> into groups of IEnumerable<string>

I have a list that I would like to break into groups of 10.

If I have an object

List<Person> allPendingPersons 

that is of length m.

Is there an elegant way in LINQ to break up allPendingPersons into one or more List objects that all have a up to 10 Persons?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

一直在等你来 2024-10-27 17:57:17

您可以编写自己的扩展方法:

public static IEnumerable<IEnumerable<T>> Partition<T>(this IEnumerable<T> sequence, int size) {
    List<T> partition = new List<T>(size);
    foreach(var item in sequence) {
        partition.Add(item);
        if (partition.Count == size) {
            yield return partition;
            partition = new List<T>(size);
        }
    }
    if (partition.Count > 0)
        yield return partition;
}

更深入地探索了这一点< /a> 在我的博客中。

You can write your own extension method:

public static IEnumerable<IEnumerable<T>> Partition<T>(this IEnumerable<T> sequence, int size) {
    List<T> partition = new List<T>(size);
    foreach(var item in sequence) {
        partition.Add(item);
        if (partition.Count == size) {
            yield return partition;
            partition = new List<T>(size);
        }
    }
    if (partition.Count > 0)
        yield return partition;
}

I explored this in more depth in my blog.

但可醉心 2024-10-27 17:57:17
 var groups = allPendingPersons.Select((p, index) => new {p,index})
                               .GroupBy(a =>a.index/10 );

如果您想处理IGrouping<,>。如果您正在寻找列表>回来你可以尝试

var listOfLists = allPendingPersons.Select((p, index) => new {p, index})
    .GroupBy(a => a.index/10)
    .Select((grp => grp.Select(g => g.p).ToList()))
    .ToList();
 var groups = allPendingPersons.Select((p, index) => new {p,index})
                               .GroupBy(a =>a.index/10 );

if you want to process IGrouping<,>. If you are looking for List> back you could try

var listOfLists = allPendingPersons.Select((p, index) => new {p, index})
    .GroupBy(a => a.index/10)
    .Select((grp => grp.Select(g => g.p).ToList()))
    .ToList();
弥繁 2024-10-27 17:57:17

.NET (Rx) 反应式扩展 有一个扩展方法这正是你想要的:

var buffered = allPendingPersons.BufferWithCount(10);

如果你想使用 LINQ 来做到这一点,你可以这样做:

var buffered =
    allPendingPersons
        .Select((p, i) => new { Group = i / 10, Person = p })
        .GroupBy(x => x.Group, x => x.Person)
        .Select(g => g.ToArray());

The Reactive Extensions for .NET (Rx) has an extension method that does exactly what you want:

var buffered = allPendingPersons.BufferWithCount(10);

If you want to do it using LINQ you could do this:

var buffered =
    allPendingPersons
        .Select((p, i) => new { Group = i / 10, Person = p })
        .GroupBy(x => x.Group, x => x.Person)
        .Select(g => g.ToArray());
耳根太软 2024-10-27 17:57:17

这不是最有效的技术,但这将产生一个 IEnumerable> 序列,每个内部序列包含十个元素:

var query = allPendingPersons.Select((x, i) => new { Value = x, Group = i / 10 })
                             .GroupBy(x => x.Group,
                                      (k, g) => g.Select(x => x.Value));

并且如果结果确实需要是一个列表-lists 而不是简单的序列,那么您可以通过添加几个 ToList 调用来创建 List>

var query = allPendingPersons.Select((x, i) => new { Value = x, Group = i / 10 })
                             .GroupBy(x => x.Group,
                                      (k, g) => g.Select(x => x.Value).ToList())
                             .ToList();

It's not the most efficient technique, but this will produce an IEnumerable<IEnumerable<Person>> sequence, with each inner sequence containing ten elements:

var query = allPendingPersons.Select((x, i) => new { Value = x, Group = i / 10 })
                             .GroupBy(x => x.Group,
                                      (k, g) => g.Select(x => x.Value));

And if the result really does need to be a list-of-lists rather than a simple sequence then you can create a List<List<Person>> instead by adding in a couple of ToList calls:

var query = allPendingPersons.Select((x, i) => new { Value = x, Group = i / 10 })
                             .GroupBy(x => x.Group,
                                      (k, g) => g.Select(x => x.Value).ToList())
                             .ToList();
小傻瓜 2024-10-27 17:57:17

尝试迭代器块:

public static IEnumerable<List<Person>> AsGroups(this List<Person> persons)
{
    var buf = new List<Person>(10);
    for (int i = 0; i<persons.Count i++;)
    {
        buf.Add(persons[i]);
        if (i%10 == 0 && buf.Count > 0)
        {
           yield return buf;
           buf = new List<Person>(10);
        }
    }
    yield return buf;
 }

Try an iterator block:

public static IEnumerable<List<Person>> AsGroups(this List<Person> persons)
{
    var buf = new List<Person>(10);
    for (int i = 0; i<persons.Count i++;)
    {
        buf.Add(persons[i]);
        if (i%10 == 0 && buf.Count > 0)
        {
           yield return buf;
           buf = new List<Person>(10);
        }
    }
    yield return buf;
 }
抠脚大汉 2024-10-27 17:57:17

LINQ中有没有一种优雅的方式

优雅的方式 性能不是很好。这是一种更高效的方法...

    public static List<List<T>> Chunk<T>(
      this List<T> theList,
      int chunkSize
    )
    {
        if (!theList.Any())
        {
            return new List<List<T>>();
        }

        List<List<T>> result = new List<List<T>>();
        List<T> currentList = new List<T>();
        result.Add(currentList);

        int i = 0;
        foreach(T item in theList)
        {
            if (i >= chunkSize)
            {
                i = 0;
                currentList = new List<T>();
                result.Add(currentList);
            }
            i += 1;
            currentList.Add(item);
        }
        return result;
    }

Is there an elegant way in LINQ

The elegant way is not very performant. Here is a more performant way...

    public static List<List<T>> Chunk<T>(
      this List<T> theList,
      int chunkSize
    )
    {
        if (!theList.Any())
        {
            return new List<List<T>>();
        }

        List<List<T>> result = new List<List<T>>();
        List<T> currentList = new List<T>();
        result.Add(currentList);

        int i = 0;
        foreach(T item in theList)
        {
            if (i >= chunkSize)
            {
                i = 0;
                currentList = new List<T>();
                result.Add(currentList);
            }
            i += 1;
            currentList.Add(item);
        }
        return result;
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文