Разбор строки из текстового файла и использование LINQ

У меня есть текстовый файл, который хранит в каждой строке список массивов int размера 2. Каждый массив разделен';' и int разделяются',' . Цифры представляют собой координаты. Например, в строке вы можете увидеть

1,0;5,9;3,2;6,7

из которых массив координат будет[1,0], [5,9], [3,2], [6,7] (int [2]). Это будет помещено в список[[1,0], [5,9], [3,2], [6,7]] . Затем этот список будет добавлен в другой список[[[1,0], [5,9], [3,2], [6,7]], [[a,b], [c,d], [e,f], [g,h]], [[i,j], [k,l], [m,n], [o,p]]] (Извините, если представление немного изворотливое). Я бы хотел помочь с разбором

1,0;5,9;3,2;6,7

добавить в список, которыйList<List<int[]>> Таким образом, структура данных хранит n наборов по n целочисленных координат. Я понял, что мне нужно использовать синтаксический анализ и, возможно, LINQ.

public class FileHandler : MonoBehaviour {

    string tileDataFile = "TileData.txt";
    List<List<int[]>> tileData = new List<List<int[]>>;
    bool FileExists()
    {
        if (File.Exists(tileDataFile))
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    void GetFileData()
    {
        if (FileExists())
        {
            StreamReader SR = new StreamReader(tileDataFile, Encoding.Default);
            using (SR)
            {
                do
                {
                    tileData.Add(SR.ReadLine().Split(';').Where())                    
                }
            }
        }
    }

}

У меня был некоторый опыт использования LINQ, но я недостаточно компетентен для решения этой проблемы. Кто-нибудь может предложить решение? Надеюсь, я достаточно хорошо объяснил.

# linq unity3d
Источник
  • 0
    требуется ли использовать текстовые файлы в этом формате? или вы полностью контролируете, как сохранять и получать данные?
  • 0
    ах нет, это просто кое-что, я решил, как я буду форматировать данные. Меня не волнует, каким образом форматируется структура данных при сохранении в текстовый файл. Мне просто нужно иметь возможность извлекать и сохранять n списков из n чисел типа int [2].
  • 0
    Это для использования в игровом проекте для одного человека, где я любитель C #.
Codelisting
за 1 против

Просто применяйте разделение, пока не прервете линию до чего-то, что можно использовать для построения списка массивов int.

var result = new List<int[]>();
foreach(var line in lines)
{
   var itemsForArray = line.Split(';');
   foreach(var intItems in itemsForArray)
   {
      var intItemsSplitted = intItems.Split(',');
      var firstValue = int.Parse(intItemsSplitted[0]);
      var secondValue = int.Parse(intItemsSplitted[1]);

      result.Add(new int[]{firstValue, secondValue});
   }
}


Подход LINQ (запрос):

var text = "1,2;2,2;1,4;0,1";
var result = (from t in text.Split(';')
              let s = t.Split(',')
              select new int[]    
              { 
                  int.Parse(s[0]),    
                  int.Parse(s[1]) 
              }).ToList();

Если вы предпочитаете синтаксис метода:

var result = text.Split(';')
    .Select(i => new int[]
    {
        int.Parse(i.Split(',')[0]),
        int.Parse(i.Split(',')[1])
    }).ToList();

Я не проводил никаких проверок, поэтому их нужно вставить туда, чтобы код был в безопасности

  • 0
    спасибо за ваш ответ, я рассматривал этот вариант, но вид переменных только оттолкнул меня и заставил искать другой вариант. Не могли бы вы предложить реализацию linq?
  • 0
    Да, минутку
  • 0
    Вы можете проверить реализацию linq
за 1 против

хорошо, так как у вас есть полный контроль над форматом данных, тогда проще сериализовать / десериализовать ваш List> напрямую без необходимости разбирать его самостоятельно, у вас есть несколько вариантов сериализации, там Newton.Json, и вы можете сериализовать его в текст Json, другой вариант - сериализовать его в двоичный файл с использованием класса BinaryFormatter .NET, и, наконец, вы можете использовать .NET XMLSerializer.

использование для всех из них простое, например, если вы выбрали конвертер Newton Json, вы загружаете пакет Nuget, а затем вызываете его следующим образом:

string serializedObject = JsonConvert.SerializeObject(YourList);

затем вы сохраняете эту строку в текстовый файл.

Теперь, чтобы получить его, вы делаете что-то вроде этого, читаете текстовый файл с сериализованным списком и помещаете его в строку, а затем:

 List<List<int[]>> myList= JsonConvert.DeserializeObject<List<List<int[]>>(serializedObject);

если вы решите использовать двоичный файл, вот статья MSDN:

https://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatters.binary.binaryformatter(v=vs.110).aspx

  • 0
    np, сериализация / десериализация намного проще, если вам нужна дополнительная помощь, я могу написать вам 3 строки кода для сохранения (Serialize) и 3 строки кода для получения данных (Deserialize), просто дайте мне знать и я плохо обновлю мои отвечать :)
за 0 против

Если вы хотите сделать это в одном выражении, вы можете использовать это:

Regex.Split( input, Regex.Escape( Environment.NewLine ) )
.Select( x => 
    x.Split( ';' ).Select( y =>
        y.Split( ',' )
        .Select( Int32.Parse )
        .ToList() )
    .ToList() )
.ToList();
за 0 против

Я предполагаю, что производительность этого не будет такой уж большой, и, честно говоря, я обычно предпочитаю использовать для этого json, но вот однострочный linq, который делает то, что вы хотите. Также абсолютно никакой безопасности, если одно из значений не является целым числом.

var line = "1,0;5,9;3,2;6,7";
            var list = line.Split(';').Select(a => a.Split(',').Select(b => int.Parse(b)).ToArray());
            foreach(var item in list){
                Console.WriteLine("a:" + item[0] + ", b:" + item[1]);
            }
Codelisting
Популярные категории
На заметку программисту