Разбиение массива на несколько массивов

1

У меня есть текстовый файл с таким содержимым:

01 Dir1
abcd
efg
hij
klm
nop
qrs
tuv
wxy
zab
yxw
vut
dcb

02 Dir2
abcd
efg
hij
klm
nop
qrs
tuv
wxy
zab
yxw
vut
dcb

Я получаю массив, который создается путем чтения файла:

string[] lines = File.ReadAllLines(path);

Это дает мне массив, который будет содержать все записи, включая пустую.

Идея текстового файла заключается в том, что после него есть папка и файлы в этой папке. Итак, "01 Dir1" - это папка и каждая строка после нее, пока пустая строка не будет файлом.

То, что я пытаюсь, состоит в том, чтобы иметь список массивов, поэтому из приведенного выше примера в списке будет два массива, один начиная с "01 Dir1" до пустой записи, а следующий от "02 Dir2" до конца.

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

Проблема с этим подходом заключается в том, что он будет иметь те же данные в разных наборах в памяти, один из массива ReadAllLines и другие субсайты от него.

  • 1
    Разве вы не можете просто разделить пространство?
  • 0
    The problem with that approach is that it will end up having the same data in different sets in memory, one from the ReadAllLines array and other the subs from it. ... Почему это проблема? Сборщик мусора примет объекты, которые вам больше не нужны, когда объект выходит из области видимости.
Показать ещё 5 комментариев
Теги:
arraylist
file-io

4 ответа

0
Лучший ответ

Таким образом, вы можете иметь Dictionary который содержит имена каталогов в качестве ключей и List<string> имен файлов в качестве значений.

Я не справлялся с исключительными ситуациями

Dictionary<string, List<string>> data = new Dictionary<string,List<string>>();
using (StreamReader reader = File.OpenText(filename))
{
    while (!reader.EndOfStream)
    {
        string dirName = reader.ReadLine();
        List<string> currentFiles = new List<string>();
        data.Add(dirName, currentFiles);
        string fileName;
        while (!reader.EndOfStream && (fileName = reader.ReadLine()).Trim() != "")
        {
            currentFiles.Add(fileName);
        }
    }
}
  • 1
    Это поможет в дальнейшем использовании словаря. Спасибо, ценю ваше время.
1

вы не что-то вроде следующего?

Это будет читать строку за строкой, и вы можете решить, что с ней делать. Таким образом, вы не получите большой массив строк, содержащий все записи. Результатом здесь будет список, содержащий строковые массивы и пропускающие пустые строки.

//This will be the resulting list of arrays
var fileArrayList = new List<string[]>();
var filereader = new System.IO.StreamReader("yourfile");
var tmpArr = new List<string>();
var line = "";
while((line = filereader.ReadLine()) != null)
{
   if(String.IsNullOrEmpty(line){
       //put this array to our list
       fileArrayList.Add(tmpArr.ToArray());
       //clean the temp one
       tmpArr.Clear();
   }else
   {
       tmpArr.Add(line);
   }
}
//add the last entry
fileArrayList.Add(tmpArr.ToArray());
tmpArr = null;
//close the stream
filereader.Close();
0
list<string> listBeforeEmpty = new list<string>();
list<string> listAfterEmpty = new list<string>();

//Indicates whether the loop is before the empty line or not
bool isEmptyLineFound = false;

 for (int i = 0; i < lines.Length; i++)
    {

     //If the empty line was found
     if (lines[i].CompareTo(@"") == 0)
            {
                isEmptyLineFound = true;
            }

    //Add the line to the right list
     if (isEmptyLineFound == false) 
          listBeforeEmpty .Add(lines[i]);
     else listAfterEmpty .Add(lines[i]);

    }
0

Я решил пойти на это ради удовольствия. Это то, к чему я придумал, он должен работать:

    private static string[] _arr = new string[] // The stuff you read from file.

    private static List<string[]> _arrays = new List<string[]>(); 

        while (_arr.Length > 0)
        {
            var a = _arr.TakeWhile(s =>
            {
                var li = _arr.ToList();
                return 
                    s != string.Empty // Take it if the string isn't empty.
                    || (s == string.Empty && li.IndexOf(s) == 0) // Or if it empty, but it the first element in the array (it the next one after we've just finished a batch)
                    || li.IndexOf(s) == _arr.Length; // And take it if it the last element (in the case of an empty string as the last element)
            }).ToArray();

            _arrays.Add(a);

            // Re-create the array to only include the stuff we haven't solved yet.
            var l = _arr.ToList();
            l.RemoveRange(0, a.Length);
            _arr = l.ToArray();
        }

Это немного хаки и может быть улучшено, но это должно быть то, с чем вы можете работать.

На стороне примечания, вы должны, вероятно, использовать альтернативный способ чтения вашего файла и определения этих отдельных массивов при чтении файла. Это более эффективно, и, возможно, тоже легче.

  • 0
    Не отвечай, если не хочешь. Покрытие полусырыми мыслями в качестве ответов тоже не помогает.
  • 0
    @Codehelp Вы правы, я отредактировал эту часть. Я действительно хотел ответить, потому что это интересный вопрос.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню