【问题标题】:A better way to count and sort by frequency?按频率计数和排序的更好方法?
【发布时间】:2021-02-23 12:46:30
【问题描述】:

我有一个这样的字符串liste

title1;duration1
title2;duration2
title1;duration3

这意味着title 显示duration 毫秒后将被下一个title 替换为下一个duration

title 可以重复。

目标是查找每个相同的title,然后添加其duration,然后创建所有不同titles 的列表,按durations 的总和降序排列。

我的做法:

string[] units = liste.split('\n');
Dictionary<string, long> d = new Dictionary<string, long>();
foreach(var row in units)
{
  string[] e = row.split(';');
  //if e[0] in d => add e[1] to d[e[0]] else set d[e[0]] to e[1]
}
//Convert d to list and sort descendingly by long.

有没有更好的办法?

【问题讨论】:

  • 您为此使用了正确的数据结构,我认为如果出现性能问题,那将是因为字符串操作。

标签: c# sorting dictionary


【解决方案1】:

我不一定建议这是最好的方法,因为它是一种难以理解且可维护的代码很重要,但是您可以使用 LINQ 在单个语句中获得结果。此解决方案假定您对自己的数据是干净的有信心 - 这意味着没有空白值或不会转换为双精度值的值等。

  1. 在换行符处分割字符串
  2. 在“;”处为每一行和子字符串投影一个对象
  3. 按标题分组
  4. 再次投影到一个汇总分组的新列表中
  5. 最后对列表进行排序。
string liste = @"title1;8.91
    title2; 3
    title1; 4.5";
    
var result = liste.Split('\n')
    .Select(l => new {
        title = l.Substring(0, l.IndexOf(';')).Trim(), 
        duration = l.Substring(l.IndexOf(';')+1, l.Length - (l.IndexOf(';')+1)).Trim()
    })
    .GroupBy(l => l.title)
    .Select(l => new { title = l.Key,  durations = l.Sum(m => double.Parse(m.duration))})
    .OrderByDescending(l => l.durations);

【讨论】:

  • 在构建这个 linq 时如何跟踪?此外,尝试将其更改为可捕获的异常,而无需围绕它进行全有或全无的尝试捕获。是的,我确实读过“此解决方案假定您对自己的数据是干净的有信心”,但这很难实现。
  • 您可以将其分解为多个步骤。就像第一步可能是创建一个标题/持续时间对的列表,并根据您决定的任何规则丢弃任何不验证的内容。一旦你有了一个干净的列表,就从 GroupBy 步骤开始。
【解决方案2】:

使用 linq:

           string input = "title1;10\n" +
                           "title2;20\n" +
                           "title1;30";
            var rows = input.Split(new char[] {'\n'}).Select(x => x.Split(new char[] {';'})).Select(y => new {title = y.First(), duration = int.Parse(y.Last())}).ToList();
            var sums = rows.GroupBy(x=> x.title).Select(x => new {title = x.Key, duration = x.Sum(y => y.duration)}).ToList();

【讨论】:

    猜你喜欢
    • 2016-06-30
    • 1970-01-01
    • 1970-01-01
    • 2013-12-28
    • 1970-01-01
    • 2013-09-10
    • 2011-07-22
    相关资源
    最近更新 更多