c# - 如何将排序后的字典输出为 CSV?

标签 c# algorithm dictionary c#-3.0

我有一个排序的字典,如下图所示:

  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

最佳答案

任务比看起来更复杂......你没有做对,因为 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();        
    }
}

关于c# - 如何将排序后的字典输出为 CSV?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26423962/

相关文章:

c# - 从 WPF WindowsFormsHost 设置 "AcceptButton"

c# - 初始化的字符串似乎包含 string.Empty

algorithm - 给定范围内所有可能对的最大按位与

algorithm - 两个移动矩形之间的最小距离

c++ - 在 C++ 中有效识别字符串数组中重复项的算法

python字典以dict为容器的奇怪行为

c# - 如何使用 C# 构建软电话(使用 SIP 协议(protocol))

c# - 从 AutoCompleteStringCollection c# 中删除重复项

C# 使用 RegEx 和字典替换 "Whole words only"

Perl `map` : When to use EXPR vs. block 形式?