Запись содержимого списка KeyValuePair в текстовые файлы - с уловкой - PullRequest
2 голосов
/ 09 марта 2011

Каков оптимальный способ записи «значений», доступных в списке, в текстовый файл?Подвох - это имя Текстового файла, должно определяться Ключом.

Например, мне удалось построить список следующим образом:

["Animal", "Lion|Roars"]
["Animal", "Tiger|Roars"]
["Bird",   "Eagle|Flies"]
["Bird",   "Parrot|Mimics"]

Нам нужно написать два файла на основе вышеупомянутого: Animal.txt и Bird.txt каждый из которых содержит только свои соответствующие значения.

Какой эффективный способ сделать это?

Спасибо сообществу SOF.

Ответы [ 5 ]

3 голосов
/ 09 марта 2011

Я бы использовал LINQ для группировки, а затем записывал каждую группу в файл сразу.Что-то простое, как это должно сделать это:

    static void WriteFiles(IEnumerable<KeyValuePair<string, string>> data)
    {
        foreach (var group in from kvp in data
                              group kvp.Value by kvp.Key)
            File.WriteAllLines(group.Key + ".txt", group);
    }
2 голосов
/ 09 марта 2011
foreach (var group in yourList.GroupBy(x => x.Key, x => x.Value))
{
    File.WriteAllLines(group.Key + ".txt", group);
}
2 голосов
/ 09 марта 2011

Вы можете попробовать группировать:

class Program
{
    static void Main()
    {
        var data = new List<KeyValuePair<string, string>>
        {
            new KeyValuePair<string, string>("Animal", "Lion|Roars"),
            new KeyValuePair<string, string>("Animal", "Tiger|Roars"),
            new KeyValuePair<string, string>("Bird", "Eagle|Flies"),
            new KeyValuePair<string, string>("Bird", "Parrot|Mimics")
        };
        var groups = data.GroupBy(x => x.Key);
        foreach (var group in groups)
        {
            var filename = Path.ChangeExtension(group.Key, "txt");
            var content = string.Join(Environment.NewLine, group.Select(x => x.Value));
            File.WriteAllText(filename, content);
        }
    }
}

, который будет генерировать:

  1. Animal.txt

    Lion|Roars
    Tiger|Roars
    
  2. Bird.txt:

    Eagle|Flies
    Parrot|Mimics
    
1 голос
/ 09 марта 2011

Вам не нужно пытаться все связать. Когда вы создаете группу, вы создаете из всех данных в списке словарь, прежде чем вы сможете записать одну строку в вывод. Это потребляет как минимум вдвое больше памяти, чем необходимо. Такая конструкция исключает ленивую обработку, поскольку вы с нетерпением читаете все в память, прежде чем сможете записать вывод.

Вместо этого вы можете обработать список один за другим и записать текущую строку в нужный файл. Это может быть так же просто, как поиск в хеш-таблице для правильного потока файлов, используя Animal или Bird в качестве ключей для выбора правильного выходного файла.

static Dictionary<string, StreamWriter> _FileMap = new Dictionary<string, StreamWriter>();

static void Main(string[] args)
{
    var data = new List<KeyValuePair<string, string>>
    {
        new KeyValuePair<string, string>("Animal", "Lion|Roars"),
        new KeyValuePair<string, string>("Animal", "Tiger|Roars"),
        new KeyValuePair<string, string>("Bird", "Eagle|Flies"),
        new KeyValuePair<string, string>("Bird", "Parrot|Mimics")
    };

    foreach (var line in data) // write data to right output file
    {
        WriteLine(line.Key, line.Value);
    }

    foreach (var stream in _FileMap) // close all open files
    {
        stream.Value.Close();
    }
}

static void WriteLine(string key, string line)
{
    StreamWriter writer = null;
    if (false == _FileMap.TryGetValue(key, out writer))
    {
        // Create file if it was not opened already
        writer = new StreamWriter(File.Create(key+".txt"));
        _FileMap.Add(key,writer);
    }
    writer.WriteLine(line);  // write dynamically to the right output file depending on passed key
}
1 голос
/ 09 марта 2011

Итак, у вас есть

List<KeyValuePair<string, string>> keyValuePairs;

и вы хотите записать их в файл, основываясь на свойстве Key для каждой пары. Хорошо, просто сгруппируйте по Key и добавьте к имени файла на основе Key.

var groups = keyValuePairs.GroupBy(x => x.Key);
foreach(var group in groups) {
    File.AppendAllLines(
        GetFilenameFromKey(group.Key),
        group.Select(x => x.Value)
    );
}

Здесь наивная версия GetFilenameFromKey равна

public string GetFilenameFromKey(string key) {
    return Path.ChangeExtension(key, "txt");
}
...