"至于"一个IEnumerable< IEnumerable的< T>> 90度IEnumerable、QUOT、LT、GT

2023-09-11 05:35:59 作者:账号已注销

我正在寻找的是一个基本操作(我敢肯定有一个名字,我只是不知道大气压)。我有这样一个矩阵:

What I'm looking for is a basic operation (Which I'm sure have a name I'm just unaware of atm). I have a matrix like:

{1,2,3}

{A,N,F}

{7,8,9}

我要变异成

{1,A,7}

{2,N,8}

{3,F,9}

(以上是对对象不是真正的值标识符。实际对象是同一类型的,无序的)

(The above are only identifiers for objects not real values. The actual objects are of the same type and unordered)

我preFER声明性的解决方案,但速度是一个因素。我将不得不把相当多的表(100K的细胞分)和慢速的版本将是关键路径上。

I'd prefer a declarative solution to it but speed is a factor. I'm going to have to turn quite a few tables (100k cells a min) and a slow version would be on the critical path.

不过我更感兴趣的是可读的解决方案。 我正在寻找替代方案的下面。 (通过替代我不是指的变化,但不同的方法)

However I'm still more interested in a readable solution. I'm looking for alternative solutions to the below. (By alternative I do not mean variations but a different approach)

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]; 
  }
}

当中两人几乎同样可读的解决方案,我会去的快,但可读性速度去之前

Amongst two almost equally readable solutions I'd go for the faster but readability goes before speed

修改 这将永远是一个方阵

EDIT It will always be a square matrix

推荐答案

我对这个实现有点玄乎。它有副作用本地的迭代器,但看起来逻辑上干净的给我。这是假定每个序列是相同的长度,但应当适用于任何。你可以把它看成是一个可变长度 邮编() 方法。它应该执行比在其他的答案发现,因为它仅使用工作所需的最低操作其他链接LINQ方案更好。也许更好,而无需使用LINQ的。甚至可能被认为是最优的。

I'm a little iffy about this implementation. It has side-effects local to the iterator but looks logically clean to me. This assumes each sequence is the same length but should work for any. You can think of it as a variable length Zip() method. It should perform better than the other linked LINQ solutions found in the other answers as it only uses the minimum operations needed to work. Probably even better without the use of LINQ. Might even be considered optimal.

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();
    }
}
 
精彩推荐