【问题标题】:How to read a 2d text file into an 2d array with PLinq如何使用 PLinq 将 2d 文本文件读入 2d 数组
【发布时间】:2015-12-02 08:34:48
【问题描述】:

我有一个这样的 .txt 文件:

1,2,3,4,5  
6,7,8,9,10  
11,12,13,14,15  
16,17,18,19,20

我想用 PLinq 将这个文件读取到一个双数组中,代码如下:

        OpenFileDialog ofd = new OpenFileDialog();
        ofd.Filter = "Text Files(*.txt)|*.txt";
        if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {
            number_of_users = File.ReadAllLines(ofd.FileName).Length;
            number_of_services = File.ReadAllLines(ofd.FileName)[0].Split(',').Length;    
            quality_of_service_array = new double[number_of_users, number_of_services]; 
            quality_of_service_array = File.ReadAllLines(ofd.FileName)
               .Select(l => l.Split(',').Select(i => double.Parse(i)).ToArray())
               .ToArray();
}

这个数组应该有 4 行 5 列。
但我得到这个错误:

无法将类型 'double[][]' 隐式转换为 'double[,]。

我知道这个错误的含义,但我不是 PLinq 专家。

【问题讨论】:

  • 您没有使用PLINQ。此外,没有一种简单的方法可以直接从 Linq 查询返回多维数组
  • 我用谷歌搜索了我的问题,我找到了这个解决方案。很明显,我不是专家。 :)

标签: c# arrays linq parallel-processing plinq


【解决方案1】:

您没有使用PLINQ。此外,从 LINQ 查询返回二维数组也不是一种简单的方法。如果你坚持使用 LINQ,你可以使用 this method 来转换它:

public T[,] JaggedToMultidimensional<T>(T[][] jaggedArray)
{
    int rows = jaggedArray.Length;
    int cols = jaggedArray.Max(subArray => subArray.Length);
    T[,] array = new T[rows, cols];
    for(int i = 0; i < rows; i++)
    {
        for(int j = 0; j < cols; j++)
        {
            array[i, j] = jaggedArray[i][j];
        }
    }
    return array;
}

然后很简单(使用AsParallel,因为您提到了 PLINQ):

double[][] quality_of_service_array = File.ReadLines(ofd.FileName).AsParallel()
    .Select(l => Array.ConvertAll(l.Split(','), double.Parse))
    .ToArray();
double[,] qos_2d = JaggedToMultidimensional(quality_of_service_array);

这假定文本文件中的格式始终正确,否则您将在double.Parse 处遇到异常。您可以使用double.TryParse 进行检查。

【讨论】:

  • 谢谢。由于 .txt 文件中的项目很大,我想减少阅读时间。
  • @Massoud:我怀疑你是否从使用 PLINQ 和 IO 方法中获得了很多(如果有的话)。高清是限制。但看到差异会很有趣。
  • @Massoud:还请注意,您不需要多次读取文件(正如Cetin 也提到的那样)。我忘记在回答中明确提及它,但我使用单个查询来创建锯齿状数组。另外,不要使用File.ReadAllLines(如您的问题)但File.ReadLines(如我的回答),后者可以在读取整个文件之前开始处理。
【解决方案2】:

您可以将锯齿状数组转换为 2D 数组,如 Tim Schmelter 所示。

在您的示例中,您不必要地一次又一次地读取同一个文件,而这与 PLINQ 没有任何关系。您可以将文件一次读入数组。即:

OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "Text Files(*.txt)|*.txt";
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
  var quality_of_service_array = File.ReadAllLines(ofd.FileName)
     .Select(l => l.Split(',').Select(i => double.Parse(i)).ToArray());
}

PS:没有第二个 ToArray() 你会得到一个 IEnumerable。对于大文件,您可以简单地在循环中使用 StreamReader 和 ReadLine 并从我认为的性能点解析哪个更有效。

【讨论】:

    猜你喜欢
    • 2015-06-26
    • 2021-02-25
    • 2020-05-19
    • 1970-01-01
    • 2021-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多