How to “zip” or “rotate” a variable number of lists?

后端 未结 8 1629
广开言路
广开言路 2020-11-27 20:47

If I have a list containing an arbitrary number of lists, like so:

var myList = new List>()
{
    new List() { \"a\",          


        
相关标签:
8条回答
  • 2020-11-27 21:11

    Here's an inefficient variant based on Matrix Transposition:

    public static class Ext
    {
        public static IEnumerable<IEnumerable<T>> Rotate<T>(
            this IEnumerable<IEnumerable<T>> src)
        {
            var matrix = src.Select(subset => subset.ToArray()).ToArray();
            var height = matrix.Length;
            var width = matrix.Max(arr => arr.Length);
    
            T[][] transpose = Enumerable
                .Range(0, width)
                .Select(_ => new T[height]).ToArray();
            for(int i=0; i<height; i++)
            {        
                for(int j=0; j<width; j++)
                {            
                    transpose[j][i] = matrix[i][j];            
                }
            }
    
            return transpose;
        }
    }
    
    0 讨论(0)
  • 2020-11-27 21:13

    You can do this by using the Select extension taking a Func<T, int, TOut>:

    var rotatedList = myList.Select(inner => inner.Select((s, i) => new {s, i}))
                            .SelectMany(a => a)
                            .GroupBy(a => a.i, a => a.s)
                            .Select(a => a.ToList()).ToList();
    

    This will give you another List<List<string>>.

    Breakdown

    .Select(inner => inner.Select((s, i) => new {s, i}))
    

    For each inner list, we project the list's content to a new anonymous object with two properties: s, the string value, and i the index of that value in the original list.

    .SelectMany(a => a)
    

    We flatten the result to a single list

    .GroupBy(a => a.i, a => a.s)
    

    We group by the i property of our anonymous object (recall this is the index) and select the s property as our values (the string only).

    .Select(a => a.ToList()).ToList();
    

    For each groups, we changed the enumerable to a list and another list for all the groups.

    0 讨论(0)
提交回复
热议问题