简体   繁体   English

一种更好的按频率计数和排序的方法?

[英]A better way to count and sort by frequency?

I have a string liste like this我有一个这样的字符串liste

title1;duration1
title2;duration2
title1;duration3

Which means that the title was shown for duration milliseconds to be replaced by the next title for the next duration .这意味着title显示的duration毫秒将被下一个title替换为下一个duration

title can repeat itself. title可以重复。

The goal is to look for each title that is the same, to then add its duration to then create a list of all distinct title s sorted descendingly by their sum of duration s.目标是查找每个相同的title ,然后添加其duration ,然后创建所有不同title的列表,按它们的duration之和降序排序。

My approach:我的做法:

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.

Is there a better way?有没有更好的办法?

I'm not necessarily suggesting this is the best way because it is kind of incomprehensible and maintainable code is important, but you can obtain your result in a single statement with LINQ.我不一定建议这是最好的方法,因为它是一种难以理解且可维护的代码很重要,但是您可以使用 LINQ 在单个语句中获得结果。 This solution assumes you have confidence in your data being clean - meaning no blank values or values that don't convert to double, etc.此解决方案假定您对自己的数据是干净的有信心 - 这意味着没有空白值或不转换为双精度值的值等。

  1. split the string on newline在换行符上拆分字符串
  2. project an object for each line and substring at ";"将 object 和 substring 投影在“;”
  3. Group by title按标题分组
  4. project again into a new list that sums the groupings再次投影到一个汇总分组的新列表中
  5. Finally sort the list.最后对列表进行排序。
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);

Use linq:使用 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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM