简体   繁体   中英

A better way to count and sort by frequency?

I have a string liste like this

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 can repeat itself.

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.

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. 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 ";"
  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:

           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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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