2015-12-02 1 views
1

У меня есть .txt файл, как это:Как читать 2d текстовый файл в 2d массив с PLINQ

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 столбцов.
Но я получаю эту ошибку:

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

Я знаю, что смысл этой ошибки, но я не эксперт в PLINQ.

+0

Вы не используете 'PLINQ'. Кроме того, нет простого способа прямого возвращения многомерного массива из запроса Linq –

+0

Я разобрал свой вопрос и нашел это решение. Понятно, что я не эксперт. :) – Massoud

+0

Неточный дубликат http://stackoverflow.com/questions/597720/what-are-the-differences-between-a-multidimensional-array-and-an-array-of-arrays –

ответ

3

Вы не используете PLINQ. Кроме того, нет простого способа вернуть 2d-массив из запроса 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, чтобы проверить его.

+0

Спасибо. из-за огромных элементов в TXT-файле, я хочу меньше времени на чтение. – Massoud

+3

@Massoud: Я сомневаюсь, что вы много выиграли от использования PLINQ с помощью методов ввода-вывода. HD - это ограничение. Но было бы интересно увидеть разницу. –

+0

@Massoud: также обратите внимание, что вам не нужно читать файл несколько раз (как упоминал [Cetin] (http://stackoverflow.com/a/34038514/284240)). Я забыл упомянуть об этом явно в своем ответе, но я использую один запрос для создания зубчатого массива. Кроме того, не используйте 'File.ReadAllLines' (как в вашем вопросе), а' File.ReadLines' (как в моем ответе), последний может начать обработку до того, как будет прочитан весь файл. –

0

Вы можете преобразовать зубчатый массив в 2D-массив, как показал Тим Шмельтер.

В вашем примере вы лишний раз читаете один и тот же файл снова и снова, и эта вещь действительно не имеет никакого отношения к 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 в цикле вместо этого и проанализировать, что было бы более эффективным с точки зрения производительности, я думаю.