2014-10-17 51 views
0

我有一個排序的字典,如下圖:如何將已排序字典輸出爲CSV?

var enteries = new SortedDictionary<IgaAdKey, IgaEntry>(); 

enter image description here

我想打印的項目爲0,則第2項,然後第4項,在一個行,CSV格式,然後去到項目1,3,5並以CSV格式打印出來。 但有些情況下,只有3個獨特的資源,或只有3個唯一的ResourceId值和只有一個不同ResourceId。 在這些情況下,我想通過寫入5個逗號(「,,,,,」)來打印空行。

這裏是我正在做,但當然我跳過新線

foreach (var pair in enteries.OrderBy(pair => pair.Key.ResourceId)) 
    { 
     if (!currResources.Contains(pair.Key.ResourceId)) 
     { 
      currResources.Add(pair.Key.ResourceId); 

      IgaEntry entry = enteries[pair.Key]; 

      streamWriter.Write(pair.Key.LocationId + ","); 
      streamWriter.Write(pair.Key.EditionId + ","); 
      streamWriter.Write(entry.mClickCount + ","); 
      streamWriter.Write(entry.mViewCount + ","); 
      streamWriter.Write(","); 
     } 
     else 
     { 
      IgaEntry entry = enteries[pair.Key]; 

      streamWriter.Write("\n"); 
      streamWriter.Write(date.ToString("yyyyMMdd") + ","); 

      int search = resourcesList.IndexOf(pair.Key.ResourceId); 
      if (search > 0) 
      { 
       for (int i = 0; i < search * 5; i++) 
       { 
        streamWriter.Write(","); 
       } 
      } 
      streamWriter.Write(pair.Key.LocationId + ","); 
      streamWriter.Write(pair.Key.EditionId + ","); 
      streamWriter.Write(entry.mClickCount + ","); 
      streamWriter.Write(entry.mViewCount + ","); 
      streamWriter.Write(","); 
     } 
    } 

} 

代碼的結果是:

enter image description here

,它應該是這樣的:

enter image description here

+0

如果什麼有超過3個資源具有相同'ResourceId'? – BartoszKP 2014-10-17 11:27:50

回答

1

任務是比它更復雜似乎...因爲StreamWriter在最後附加了文本,所以如果您已經爲第一個ResourceId(寫入2行)打印了2個條目,則不能返回第一行來打印第二個ResourceId。

我編寫和調試一些代碼,這是保證編譯能力和運行能力;)

class CSVOrderById 
{ 
    class IgaAdKey: IComparable 
    { 
     public int ResourceId { get; set; } 
     public int EditionId { get; set; } 
     public int LocationId { get; set; } 

     //required if added to Dictionary, not the correct implementation though 
     public int CompareTo(object obj) 
     { 
      IgaAdKey key = obj as IgaAdKey; 

      if (key == null) 
       return -1; 
      else 
       return (ResourceId + EditionId + LocationId).CompareTo(key.ResourceId + key.EditionId + key.LocationId);     
     } 
    } 

    class IgaEntry 
    { 
     public int mClickCount { get; set; } 
     public int mViewCount { get; set; } 
    } 

    public static void Test() 
    { 
     var enteries = new SortedDictionary<IgaAdKey, IgaEntry>(); 

     enteries.Add(new IgaAdKey(){ ResourceId = 123, EditionId = 12313, LocationId = 2}, new IgaEntry(){ mClickCount = 2, mViewCount = 10}); 
     enteries.Add(new IgaAdKey(){ ResourceId = 123, EditionId = 12332, LocationId = 2}, new IgaEntry(){ mClickCount = 2, mViewCount = 10}); 
     enteries.Add(new IgaAdKey(){ ResourceId = 234, EditionId = 23413, LocationId = 1}, new IgaEntry(){ mClickCount = 2, mViewCount = 10}); 
     //enteries.Add(new IgaAdKey(){ ResourceId = 234, EditionId = 23455, LocationId = 1}, new IgaEntry(){ mClickCount = 2, mViewCount = 10}); 
     enteries.Add(new IgaAdKey(){ ResourceId = 789, EditionId = 78922, LocationId = 2}, new IgaEntry(){ mClickCount = 2, mViewCount = 10}); 
     //enteries.Add(new IgaAdKey(){ ResourceId = 789, EditionId = 78999, LocationId = 2}, new IgaEntry(){ mClickCount = 2, mViewCount = 10}); 

     var list = enteries.ToList(); //inorder to call FindAll() 
     var dic = new Dictionary<int, List<KeyValuePair<IgaAdKey, IgaEntry>>>(); 
     var streamWriter = new StreamWriter("a.csv"); 

     //first find all ResourceId's, 
     HashSet<int> currResourcesId = new HashSet<int>(); 
     foreach (var pair in list) 
     { 
      currResourcesId.Add(pair.Key.ResourceId); //result: 3 unique ResourceId's 
     } 
     int maxCount = 0; 
     foreach (int resourceId in currResourcesId) 
     { 
      List<KeyValuePair<IgaAdKey, IgaEntry>> sortedByResourcesId = list.FindAll(pair => pair.Key.ResourceId == resourceId); 
      dic.Add(resourceId, sortedByResourcesId); 
      if (sortedByResourcesId.Count > maxCount) 
       maxCount = sortedByResourcesId.Count; //result: maxCount = 2 
     } 

     //so we write 2 rows 
     for (int run = 0; run < maxCount; run++) 
     { 
      streamWriter.Write(System.DateTime.Now.ToString("yyyyMMdd") + ","); 
      foreach (int resourceId in currResourcesId) 
      { 
       if (dic[resourceId].Count > run) 
       { 
        streamWriter.Write(dic[resourceId][run].Key.LocationId + ","); 
        streamWriter.Write(dic[resourceId][run].Key.EditionId + ","); 
        streamWriter.Write(dic[resourceId][run].Value.mClickCount + ","); 
        streamWriter.Write(dic[resourceId][run].Value.mViewCount + ","); 
        streamWriter.Write(","); 
       } 
       else 
       { 
        streamWriter.Write(",,,,,"); 
       } 
      } 

      if (run < maxCount) 
       streamWriter.WriteLine(); 
     } 

     streamWriter.Close();   
    } 
} 
+0

好算法!我的問題實際上是我可以從我編寫的入門文件中返回,這是因爲streamwritter追加。 – 2014-10-18 02:37:51

1

T他的數據只需要一個「group by」按照ResourceId來組織它。

例如,使用的GroupBy()命令由RESOURCEID的數據,然後創建具有應打印在同一行中的其他字段的投影:

static void Main(string[] args) 
{ 
    //TODO: Run your method to build entries. 
    var entries = TestFill(); 

    var tree = entries.GroupBy(
     pair => pair.Key.ResourceId, 
     pair => new {EditionId = pair.Key.EditionId, LocationId = pair.Key.LocationId, ClickCount = pair.Value.ClickCount, ViewCount = pair.Value.ViewCount}, 
     (key, data) => new {ResourceId = key, Statistics = data.ToList()}); 

    var count = 0; 
    foreach (var node in tree) 
    { 
     Console.Write("[" + (count++) + "]\t" + node.ResourceId); 
     foreach (var item in node.Statistics) 
     { 
      Console.Write(String.Format(",{0},{1},{2},{3}", item.LocationId, item.EditionId, item.ClickCount, item.ViewCount)); 
     } 
     Console.WriteLine(); 

    } 

    Console.WriteLine("Press enter to continue..."); 
    Console.ReadLine(); 
}