我有一个排序字典,如下图所示:
var enteries = new SortedDictionary<IgaAdKey, IgaEntry>();
我想在第一行,CSV格式中打印项目0,然后是项目2,然后是项目4,然后转到第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(",");
}
}
}
该代码的结果是:
应该是这样的:
答案 0 :(得分:1)
数据只需要一个“分组依据”来根据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();
}
答案 1 :(得分: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();
}
}