首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >“转弯”IEnumerable<IEnumerable<T>> 90度

“转弯”IEnumerable<IEnumerable<T>> 90度
EN

Stack Overflow用户
提问于 2011-02-18 09:31:57
回答 6查看 1.6K关注 0票数 8

我正在寻找的是一个基本的操作(我肯定有一个名字,我只是不知道atm)。我有一个矩阵,如:

{1,2,3}

{A,N,F}

{7,8,9]

我想变异成

{1,A,7}

{2,N,8}

{3,F,9}

(以上只是对象的标识符,而不是实值。实际的对象是相同类型和无序的)

比起它,我更喜欢声明式的解决方案,但是速度是一个因素。我将不得不转动相当多的表(每分钟100 k单元格),而一个缓慢的版本将在关键的路径上。

然而,我仍然更感兴趣的是一个可读的解决方案。我正在寻找以下的替代解决方案。(我所说的替代方案并不是指变化,而是一种不同的方法)

代码语言:javascript
复制
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]; 
  }
}

在两个几乎相同可读性的解决方案中,我会选择速度更快但可读性高于速度的解决方案。

编辑它将永远是一个方阵

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-02-18 09:58:05

我对这个实现有点怀疑。它对迭代器有局部的副作用,但在我看来逻辑上是干净的。这假设每个序列都是相同的长度,但应该适用于任何序列。您可以将其看作是可变长度的Zip()方法。它应该比在其他答案中找到的其他链接LINQ解决方案执行得更好,因为它只使用工作所需的最小操作。如果不使用LINQ,可能会更好。甚至可能被认为是最佳选择。

代码语言:javascript
复制
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();
    }
}
票数 11
EN

Stack Overflow用户

发布于 2011-02-18 09:41:34

看看这个找到这里的扩展方法。

代码语言:javascript
复制
/// <summary>
/// Swaps the rows and columns of a nested sequence.
/// </summary>
/// <typeparam name="T">The type of elements in the sequence.</typeparam>
/// <param name="source">The source sequence.</param>
/// <returns>A sequence whose rows and columns are swapped.</returns>
public static IEnumerable<IEnumerable<T>> Transpose<T>(
         this IEnumerable<IEnumerable<T>> source)
{
    return from row in source
           from col in row.Select(
               (x, i) => new KeyValuePair<int, T>(i, x))
           group col.Value by col.Key into c
           select c as IEnumerable<T>;
}

我不确定性能,但代码看起来很优雅。

票数 3
EN

Stack Overflow用户

发布于 2011-02-18 09:47:03

你的问题似乎意味着你想要修改原始矩阵。

如果是这样的话,如果您能够将矩阵存储为一个IList<IList<T>> matrix,那么这将只在正方形矩阵的情况下起作用。

代码语言:javascript
复制
for(int i = 0; i < matrix.Count; ++i)
{
    for(int j = 0; j < i; ++j)
    {
        T temp = matrix[i][j];
        matrix[i][j] = matrix[j][i];
        matrix[j][i] = temp
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5039617

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档