c# - IEnumerable<object[]> 和 IEnumerable<object>[] 之间的优雅转换

标签 c# arrays iterator enumerable

有什么方法可以转换IEnumerable<int[]>IEnumerable<int>[] ?具体来说,我有以下 IEnumerable:

    IEnumerable<int[]> data = new List<int[]>()
    {
    new int[]{1,11},
    new int[]{2,22},
    new int[]{3,33},
    new int[]{4,44},
    // ...
    // ...
    };
我想把它变成以下形状:
    IEnumerable<int>[] data = new List<int>[] 
    { 
    new List<int>(){1,2,3,4 },
    new List<int>(){11,22,33,44}
    };
到目前为止,我想出的唯一解决方案如下:
public static IEnumerable<int>[] Convert(IEnumerable<int[]> data)
{
    var length = data.First().Length;
    var output = new List<int>[length];
    for (int i = 0; i < length; i++)   
        output[i] = new List<int>();
    foreach (var entry in data) 
    {
        for (int i = 0; i < length; i++)    
        {
            output[i].Add(entry[i]);
        }
    }
    return output;
}
虽然这并不理想,因为我需要遍历整个数据集。所需的解决方案是利用 LINQ 或内置迭代器模式功能 ( yield return )。这个问题有没有更好的解决方案?

最佳答案

如果您不介意 data 的多次枚举, 你可以这样做:

public static IEnumerable<int>[] Convert(IEnumerable<int[]> data)
{
    var length = data.First().Length;
    var output = new IEnumerable<int>[length];
    for (int i = 0; i < length; i++)
    {
        output[i] = CustomEnumerable(i);
    }

    return output;

    IEnumerable<int> CustomEnumerable(int index)
    {
        foreach (var entry in data) 
        {
            yield return entry[index];
        }
    }
}
如您所见,我没有填充列表,而是返回自定义 IEnumerable<int> s,它们是用本地迭代器函数创建的(使用 yield return)。
如果您关心迭代 data只有一次,你可以做这样的事情:
IEnumerable<int>[] Convert(IEnumerable<int[]> data)
{
    var found = new List<int[]>();
    using var enumerator = data.GetEnumerator();
    var proxy = ProxyEnumerable();
    
    var length = proxy.First().Length;
    var output = new IEnumerable<int>[length];
    for (int i = 0; i < length; i++)
    {
        output[i] = CustomEnumerable(i);
    }

    return output;

    IEnumerable<int> CustomEnumerable(int index)
    {
        foreach (var entry in proxy) 
        {
            yield return entry[index];
        }
    }
    
    IEnumerable<int[]> ProxyEnumerable()
    {    
        foreach (var value in found)
        {
            yield return value;
        }

        while (enumerator.MoveNext())
        {
            var value = enumerator.Current;
            found.Add(value);
            yield return value;
        }
    }
}
我在这里添加了另一个 IEnumerable<int[]>正在填充缓存 List<int[]>当我们迭代它时。所以data只迭代一次,后续迭代使用缓存。
Try it online .

关于c# - IEnumerable<object[]> 和 IEnumerable<object>[] 之间的优雅转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66930797/

相关文章:

c++ - 释放一对 vector 中对象的内存

C# SQL 创建表,如果它不存在

c# - C#如何调查为什么我的服务意外停止

c# - 用 html 标签包围 Eval

c - 遍历 C 数组

c++ - 从 std::map<std::basic_string<char>,std::pair<int,int(*)(const std::vector::Mat

c# - 如何在主页上显示动态时钟?

php - 使用表单在 MySQL DB 中存储和检索关联数组

c++ - C++中指向结构的指针数组

c++ - 无法在 C++ 中创建模板<typename T> vector<T>::iterator