C# 反转/旋转列表(List

C# 反转/旋转列表(List,c#,list,C#,List,我有一张名单。我想将该行还原为列,将列还原为行。若内部列表中的元素数相同,我可以将其反转。但若内部列表中的元素数量不同,我就不能这样做 假设我有这个清单 1 2 3 4 5 6 7 8 我得到这个输出 1 5 2 6 3 7 4 8 但是如果我有这样的输入,那么我会收到错误 1 2 3 4 5 6 7 这是密码 var invertedRows = matrix.Select(row => row.Count).Concat(new[] {0}).Max(); var result

我有一张名单。我想将该行还原为列,将列还原为行。若内部列表中的元素数相同,我可以将其反转。但若内部列表中的元素数量不同,我就不能这样做

假设我有这个清单

1 2 3 4
5 6 7 8
我得到这个输出

1 5
2 6
3 7
4 8
但是如果我有这样的输入,那么我会收到错误

1 
2 3 4
5 6 7
这是密码

var invertedRows = matrix.Select(row => row.Count).Concat(new[] {0}).Max();
var result = new Point3D[invertedRows][];
for (var i = 0; i < invertedRows; i++)
{
    var invertedColumns = matrix[i].Count;
    result[i] = new Point3D[invertedColumns];
    for (var j = 0; j < invertedColumns; j++)
        result[i][j] = matrix[j][i];
}
matrix.Clear();
matrix.AddRange(result.Select(row => row.ToList()));

你的输入长度不一样

您希望在输出的第一列中看到什么?
您的代码是如何做到这一点的?

您的输入长度不同

您希望在输出的第一列中看到什么? 您的代码是如何做到这一点的?

更新:将第一个LINQ方法移到了底部,因为这样更好

您可以使用此扩展方法:

public static List<List<T>> Pivot<T>(this List<List<T>> inputLists, bool removeEmpty, T defaultVal = default(T))
{
    if (inputLists == null) throw new ArgumentNullException("inputLists");
    if(removeEmpty && !object.Equals(defaultVal, default(T))) throw new ArgumentException("You cannot provide a default value and removeEmpty at the same time!", "removeEmpty");

    int maxCount = inputLists.Max(l => l.Count);
    List<List<T>> outputLists = new List<List<T>>(maxCount);
    for(int i = 0; i < maxCount; i++)
    {
        List<T> list = new List<T>();
        outputLists.Add(list);
        for (int index = 0; index < inputLists.Count; index++)
        {
            List<T> inputList = inputLists[index];
            bool listSmaller = inputList.Count <= i;
            if (listSmaller)
            {
                if (!removeEmpty)
                    list.Add(defaultVal);
            }
            else
                list.Add(inputList[i]);
        }
    }
    return outputLists;
}
旧的、可接受的版本,效率较低,不支持不同的默认值和删除空元素,如下所示:

public static List<List<T>> Pivot<T>(this List<List<T>> inputLists)
{
    int maxCount = inputLists.Max(l => l.Count);

    var result = Enumerable.Range(0, maxCount)
        .Select(index => inputLists.Select(list => list.ElementAtOrDefault(index))
                                   .ToList())
        .ToList();
    return result;
}
更新:将第一个LINQ方法移到底部,因为这样更好

您可以使用此扩展方法:

public static List<List<T>> Pivot<T>(this List<List<T>> inputLists, bool removeEmpty, T defaultVal = default(T))
{
    if (inputLists == null) throw new ArgumentNullException("inputLists");
    if(removeEmpty && !object.Equals(defaultVal, default(T))) throw new ArgumentException("You cannot provide a default value and removeEmpty at the same time!", "removeEmpty");

    int maxCount = inputLists.Max(l => l.Count);
    List<List<T>> outputLists = new List<List<T>>(maxCount);
    for(int i = 0; i < maxCount; i++)
    {
        List<T> list = new List<T>();
        outputLists.Add(list);
        for (int index = 0; index < inputLists.Count; index++)
        {
            List<T> inputList = inputLists[index];
            bool listSmaller = inputList.Count <= i;
            if (listSmaller)
            {
                if (!removeEmpty)
                    list.Add(defaultVal);
            }
            else
                list.Add(inputList[i]);
        }
    }
    return outputLists;
}
旧的、可接受的版本,效率较低,不支持不同的默认值和删除空元素,如下所示:

public static List<List<T>> Pivot<T>(this List<List<T>> inputLists)
{
    int maxCount = inputLists.Max(l => l.Count);

    var result = Enumerable.Range(0, maxCount)
        .Select(index => inputLists.Select(list => list.ElementAtOrDefault(index))
                                   .ToList())
        .ToList();
    return result;
}

代码应该是这样的

List<List<int>> cols = new List<List<int>>();
cols.Add(new List<int>() { 1 });
cols.Add(new List<int>() { 2,3,4 });
cols.Add(new List<int>() { 5,6,7 });

int[][] result = new int[100][];

for (int i = 0; i < cols.Count; i++)
{
    for (int j = 0; j < cols[i].Count; j++)
    {
        if (result[j] == null)
        {
            result[j] = new int[100];                        
        }
        if (cols[i].Count < j)
        {
            result[j][i] = 0;
        } else
        {
         result[j][i] = cols[i][j];
        }
    }
}

如果你调试你的代码,你应该很容易找到问题的确切位置。可能类似于从3列数组/列表中调用第4列。

代码应该是这样的

List<List<int>> cols = new List<List<int>>();
cols.Add(new List<int>() { 1 });
cols.Add(new List<int>() { 2,3,4 });
cols.Add(new List<int>() { 5,6,7 });

int[][] result = new int[100][];

for (int i = 0; i < cols.Count; i++)
{
    for (int j = 0; j < cols[i].Count; j++)
    {
        if (result[j] == null)
        {
            result[j] = new int[100];                        
        }
        if (cols[i].Count < j)
        {
            result[j][i] = 0;
        } else
        {
         result[j][i] = cols[i][j];
        }
    }
}

如果你调试你的代码,你应该很容易找到问题的确切位置。可能类似于从3列数组/列表中调用第4列。

您会收到什么错误?行结果[i][j]=矩阵[j][i]上的IndexAutofBound异常;如果这是输入,您希望输出是什么?您试图做什么来修复它?您收到了什么错误?行结果[i][j]=矩阵[j][i]上的IndexAutofBound异常;如果这是输入,您希望输出是什么?你试图做什么来修复它?我的代码不允许这种不同的长度。这就是问题所在。我知道,你没有要求一个编码的解决方案。你实际上没有问任何问题!我的代码不允许这种不同的长度。这就是问题所在。我知道,你没有要求一个编码的解决方案。你实际上没有问任何问题!我尝试了这段代码,正如您所说,它将添加默认值。有没有办法删除第二行第一列中的默认值0,依此类推?@FaisalHafeez:什么意思是删除?值类型必须有一个值。例如,如果您使用列表,您将得到null。我有一个列表。所以它将是空的。我正在添加额外的循环以删除此中的空值,@FaisalHafeez:注意,我已更新了我的答案以提供更好的方法。我尝试了此代码,正如您所说,它将添加默认值。有没有办法删除第二行第一列中的默认值0,依此类推?@FaisalHafeez:什么意思是删除?值类型必须有一个值。例如,如果您使用列表,您将得到null。我有一个列表。所以它将是空的。我正在添加额外的循环,以从中删除空值,@FaisalHafeez:注意,我已经更新了我的答案,以提供更好的方法。
List<List<int>> cols = new List<List<int>>();
cols.Add(new List<int>() { 1 });
cols.Add(new List<int>() { 2,3,4 });
cols.Add(new List<int>() { 5,6,7 });

int[][] result = new int[100][];

for (int i = 0; i < cols.Count; i++)
{
    for (int j = 0; j < cols[i].Count; j++)
    {
        if (result[j] == null)
        {
            result[j] = new int[100];                        
        }
        if (cols[i].Count < j)
        {
            result[j][i] = 0;
        } else
        {
         result[j][i] = cols[i][j];
        }
    }
}