【问题标题】:Dictionary group by value字典按值分组
【发布时间】:2019-12-12 08:21:40
【问题描述】:

我有一个TimeEntry class 和一个Dictionary,其中Id 作为键,其他属性作为值。现在我想按Category 的值对字典进行分组

 class TimeEntry
    {
        public int Id { get; set; }
        public string StartTime { get; set; }
        public string EndTime { get; set; }
        public string Task { get; set; }
        public string Category { get; set; }

        public override string ToString()
        {
            return string.Format($"Start Time: {StartTime}, EndTime: {EndTime}, Task: {Task}, Category {Category}");
        }
    }
private readonly IDictionary<int, TimeEntry> _timeEntries;

我想显示如下内容:

Household 
   00:30:00 do something
   00:30:00 do some stuff
work 
   01:30:00 go to work 
   00:30:00 to some work thing

必须按类别分组

【问题讨论】:

  • 每个值都有不同的键
  • 采用Values 并使用LINQ 的GroupBy 可能是一种简单的方法。然后将输出转换为您想要的任何格式,例如列表字典
  • 我已经尝试过使用 LINQ,但我不太擅长

标签: c# linq dictionary group-by


【解决方案1】:

您正在 Linq 中寻找GroupBy,例如

using System.Linq;

...

_timeEntries                       // from given dictionary we want
  .Values                          //   Values
  .GroupBy(item => item.Category)  //   Grouped By Category

例如:

string report = string.Join(Environment.NewLine, _timeEntries
  .Values
  .GroupBy(item => item.Category)
//.OrderBy(group => group.Key, StringComparer.CurrentCultureIgnoreCase)
  .Select(group => 
     $"{group.Key}\r\n  {string.Join("\r\n  ", group.Select(item => $"{item.StartTime} {item.Task}"))}"));

唯一的困难是在最终的Select表示 group

【讨论】:

  • 太好了,谢谢。给你的另一个问题是,我如何将所有开始时间汇总在一个类别中?
  • @nurix:好吧,我怀疑你是否可以 sum StartTime。比如说,12 Dec 2019 15:55:505 Oct 2010 23:50:50 怎么能相加?无论如何,我建议StartTimeEndTime 不是string,而是DateTimeTimeSpan 等。
  • 好吧,我有一个代替 StartTime 的方法,它返回一个 TimeSpan,所以它应该是可能的,不是吗?
  • @nurix: 是的,TimeSpan(即持续时间)可以很容易地求和(例如,01:12:05 + 03:58:40 == 05:10:45
  • 类似这样的事情:我们不能Sum TimeSpan excplicly,但我们可以总结 secondsL TimeSpan result = TimeSpan.FromSeconds(items.Sum(item =&gt; item.f StartTime(/*your method */) .TotalSeconds));
【解决方案2】:

这样的?

_timeEntries.OrderBy(x => x.Value.Category).ThenBy(x => x.Value.StartTime)

类别 -> 开始时间。

您可以根据需要添加任意数量:

_timeEntries.OrderBy(x => x.Value.Category).ThenBy(x => x.Value.StartTime).ThenBy(x => x.Value.EndTime).ThenByDescending(x => x.Value.Task)

类别 -> 开始时间 -> 结束时间 -> (降序)任务 等等

【讨论】:

    【解决方案3】:

    首先,如果您想对日期(开始和结束)进行一些计算,则需要将其更改为 DateTime:

    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }
    

    如果你更喜欢命令式的方式:

    foreach (var group in _timeEntries.GroupBy(x => x.Value.Category))
    {
        Console.WriteLine(group.Key);
        foreach (var entry in group)
        {
            var timespan = entry.Value.EndTime - entry.Value.StartTime;
            Console.WriteLine($"  {timespan.ToString(@"hh\:mm\:ss")} {entry.Value.Task}");
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多