LINQ中的列表转换为列

13
给定一个IEnumerable和行数,我想将它转换为IEnumerable>,如下所示:
输入:
RowCount: 3
List: [1,2,3,4,5,6,7]
输出:
[ [1,4,7] [2,5] [3,6] ]
编辑 我希望这适用于任何IEnumerable,不依赖于T是Int32。
如何使用LINQ进行此操作?
4个回答

16
这样做就可以了:
var list = new List<object> { 1, "two", 3, 4, 5, 6 ,7 };
int count = 3;
var rows = list.Select((item, index) => new { Item = item, Index = index })
            .GroupBy(o => o.Index % count)
            .Select(g => g.Select(o => o.Item));

它应该适用于任何可枚举对象


这个可以解决问题,不过效率如何呢?它会多次遍历列表吗? - Sam Saffron
@Sam Saffron - 我非常怀疑。这些Linq扩展方法在大部分情况下都实现得相当不错。我稍后会用Reflector查看一下并告诉你。 - David M
理想情况下,我希望这也能适用于... Enumerable.Range(1, 10).Select(_ => "a").ToList(); - Sam Saffron
好的,我修改了这个答案,使其适用于任何类型的列表。这样可以避免重复回答。 - Sam Saffron
@Sam:是的,使用扩展方法会增加一些开销,因此总是有可能通过手动编写代码来使其稍微快一些。另一方面,这些扩展方法编写得很好,使用它们可以让代码更简单,所以通常不值得试图对它们进行改进。 - Guffa
显示剩余5条评论

2
var src = new List<int> { 2, 4, 8, 16, 23, 42, 101 };
var i = 0;
var answer = src.GroupBy(item => i++ % 3)
                .Select(item => item.ToArray())
                .ToArray();

嘿嘿,通过这个技巧,我们可以避免使用临时变量,但代码会变得难以阅读:

        var src = new int[] { 4, 8, 15, 16, 23, 42, 101 };

        var b = Enumerable.Range(0, src.Length)
                   .Select(index => index)
                   .GroupBy(index => index % 3)
                   .Select(indexes => indexes.Select(index => src[index]).ToArray())
                   .ToArray();

1

如果你需要的是三个一组,那么这将获取三个一组的内容。

虽然这种方法有点恶劣 :-)

int[] list = new [] {1,2,3,4,5,6,7};

    int count = 0;

    var x =
        from i in list.Where((c,i)=> i%3==0)
        let grp = list.Skip(count).Take(3)
        let temp = (count+=3)
        select new {
            grp
        };

0

类似这样的代码应该可以运行。

int[] list = new[] {1,2,3,4,5,6,7};
int[] offsets = new[] {0,1,2};
int[][] sorted = 
    offsets.Select((offset) => list.TakeWhile((_,ix,_) => ix % 3 == offset))

警告:未经测试。我不懂C#编程,但是思路应该很清晰。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接