我有一份清单。我想恢复这个(行变成列,列成为行。如果内部列表中的元素数量相同,我可以反转它。但是如果内部列表中的元素数量不同,我无法这样做。
让我说我有这个清单
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()));
答案 0 :(得分:2)
更新 :(将第一个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;
}
用法:
List<List<int>> lists = new List<List<int>>();
lists.Add(new List<int> { 1 });
lists.Add(new List<int> { 2,3 });
lists.Add(new List<int> { 4,5,6 });
List<List<int>> result = lists.Pivot(true);
foreach(List<int> list in result)
Console.WriteLine(string.Join(",", list));
输出:
1,2,4
3,5
6
旧,接受的效率较低且不支持不同默认值并删除以下空元素的版本:
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>> lists = new List<List<int>>();
lists.Add(new List<int> { 1 });
lists.Add(new List<int> { 2,3 });
lists.Add(new List<int> { 4,5,6 });
List<List<int>> result = lists.Pivot();
foreach(List<int> list in result)
Console.WriteLine(string.Join(",", list));
输出:
1,2,4
0,3,5
0,0,6
答案 1 :(得分:1)
你输入的长度不一样。
您希望在输出的第一列中看到什么? 你的代码如何允许这个?
答案 2 :(得分:1)
代码看起来应该是这样的
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列。