2011-03-09 57 views
2

將List中可用的「Values」寫入Text文件的最佳方法是什麼?捕獲的是文本文件的名稱應由Key確定。將KeyValuePair列表的內容寫入文本文件 - 帶有一個catch

例如,我設法建立這樣的名單:

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

我們需要根據上面寫兩個文件:Animal.txtBird.txt每個包含各自的價值只要。

什麼是有效的方法來做到這一點?

謝謝SOF社區。

回答

1

你並不需要嘗試linqify一切。當你創建一個分組時,你可以從列表中的所有數據中創建一個字典,然後你可以寫一行到輸出。這將消耗至少兩倍的內存,因爲它是必要的。 這種設計消除了延遲處理,因爲在寫入輸出之前,您正急切地將所有內容讀入內存。

相反,您可以逐個處理列表,並將當前行寫入正確的文件。這可以像使用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 
} 
+0

此邏輯是否可以在不對密鑰和文件名進行硬編碼的情況下工作? – FMFF 2011-03-09 20:22:28

+1

確定我已經更新了代碼。動態處理輸出文件的邏輯在WriteLine方法中。 – 2011-03-09 20:33:20

2

您可以嘗試分組:

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 
    
3

我會使用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); 
    } 
1

所以,你必須

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"); 
} 
2
foreach (var group in yourList.GroupBy(x => x.Key, x => x.Value)) 
{ 
    File.WriteAllLines(group.Key + ".txt", group); 
} 
+0

您的解決方案與我的驚人相似。英雄所見略同! – Gabe 2011-03-09 18:08:20

相關問題