Run*_* FS 8 c# linq algorithm declarative
我正在寻找的是一个基本的操作(我肯定有一个名字,我只是没有意识到atm).我有一个矩阵像:
{1,2,3}
{A,N,F}
{7,8,9}
我想改变它
{1,A,7}
{2,N,8}
{3,F,9}
(以上只是对象的标识符而不是实际值.实际对象属于同一类型且无序)
我更喜欢它的声明性解决方案,但速度是一个因素.我将不得不转动相当多的表(每分钟100k个单元),而慢速版将在关键路径上.
但是我对可读解决方案仍然更感兴趣.我正在寻找下面的替代解决方案.(换句话说,我不是指变化,而是一种不同的方法)
var arrays = rows.Select(row => row.ToArray());
var cellCount = arrays.First().Length;
for(var i = 0;i<cellCount;i++){
yield return GetRow(i,arrays);
}
IEnumerable<T> GetRow(int i,IEnumerable<T[]> rows){
foreach(var row in rows}{
yield return row[i];
}
}
Run Code Online (Sandbox Code Playgroud)
在两个几乎同样可读的解决方案中,我会更快,但可读性在速度之前
编辑 它将始终是一个方阵
Jef*_*ado 10
我对这个实现有点不确定.它具有迭代器本地的副作用,但对我来说看起来很干净.这假定每个序列长度相同但应该适用于任何序列.您可以将其视为可变长度Zip()方法.它应该比其他答案中找到的其他链接LINQ解决方案表现更好,因为它只使用工作所需的最少操作.如果不使用LINQ,可能会更好.甚至可能被认为是最佳的.
public static IEnumerable<IEnumerable<T>> Transpose<T>(this IEnumerable<IEnumerable<T>> source)
{
if (source == null) throw new ArgumentNullException("source");
var enumerators = source.Select(x => x.GetEnumerator()).ToArray();
try
{
while (enumerators.All(x => x.MoveNext()))
{
yield return enumerators.Select(x => x.Current).ToArray();
}
}
finally
{
foreach (var enumerator in enumerators)
enumerator.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
只是一个快速谷歌搜索揭示了这些解决方案: