1

I have a .txt file like this:

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

I want to read this file to an double array with PLinq with this code:

        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();
}

This array should have 4 rows and 5 columns.
But I get this error:

Cannot implicitly convert type 'double[][]' to 'double[,].

I know the meaning of this error but I'm not expert in PLinq.

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Massoud
  • 361
  • 1
  • 2
  • 16
  • You are not using `PLINQ`. Also, there isn't an easy way of directly returning a multidimensional array from a Linq query – Tim Schmelter Dec 02 '15 at 08:36
  • I googled my question and I found this solution. That's clear that i'm not an expert. :) – Massoud Dec 02 '15 at 08:38
  • Not an exact duplicate http://stackoverflow.com/questions/597720/what-are-the-differences-between-a-multidimensional-array-and-an-array-of-arrays – Cheng Chen Dec 02 '15 at 08:43

2 Answers2

3

You are not using PLINQ. Also, there isn't an easy way of returning a 2d-array from a LINQ query. If you insist on LINQ you could use this method to convert it:

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

Then it's simple (used AsParallel because you've mentioned 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);

This presumes that the format in the text-file is always correct, otherwise you're getting an exception at double.Parse. You could use double.TryParse to check it.

Community
  • 1
  • 1
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • Thanks. because of huge items in .txt file, I want to less my reading time. – Massoud Dec 02 '15 at 08:48
  • 3
    @Massoud: i doubt that you gain much(if anything at all) from using PLINQ with IO methods. The HD is the limitation. But would be interesting to see the difference. – Tim Schmelter Dec 02 '15 at 08:49
  • @Massoud: also note that you don't need to read the file multiple times (as [Cetin](http://stackoverflow.com/a/34038514/284240) also has mentioned). I've forgotten to mention it explicitly in my answer but i'm using a single query to create the jagged array. Also, don't use `File.ReadAllLines`(as in your question) but `File.ReadLines`(as in my answer), the latter can start processing before the whole file is read. – Tim Schmelter Dec 02 '15 at 09:05
0

You can convert a jagged array into a 2D array as Tim Schmelter showed.

In your sample, you are unnecessarily reading the same file again and again and this thing really doesn't have anything to do with PLINQ. You can read the file once into an array. ie:

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: Not having second ToArray() you would get an IEnumerable. For a large file, you could simply use a StreamReader and ReadLine in a loop instead and parse which would be more effective from a performance point I think.

Cetin Basoz
  • 22,495
  • 3
  • 31
  • 39