根据封闭的时间戳重新排序字符串列表

时间:2019-10-06 16:05:01

标签: c#

使用C#WinForms。我有两个列表:

第一个列表:字符串按时间戳在括号内排序。

List<string> lst1 = new List<string>();
//TimeStamps Between brackets
lst1.Add("Attack(1:05)");
lst1.Add("MoveUp(1:35)");
lst1.Add("MoveDown(1:48)");
lst1.Add("MoveLeft(2:15)");
lst1.Add("MoveDown(2:24)");
lst1.Add("MoveUp(2:50)");
lst1.Add("MoveLeft(3:04)");
lst1.Add("MoveUp(5:15)");
lst1.Add("MoveLeft(7:30)");
//ETC.

第二个列表:再次!字符串按括号内的时间戳排序。

List<string> lst2 = new List<string>();
//TimeStamps Between brackets
lst2.Add("Armor Lvl1(0:04)");
lst2.Add("Loom(0:10)");
lst2.Add("Balistics(4:42)");
lst2.Add("Mail Armor(5:02)");
lst2.Add("Ring(6:12)");
lst2.Add("Fire Holes(8:44)");
lst2.Add("Attack Lvl2(10:13)");
lst2.Add("Defence Lvl1(12:33)");
lst2.Add("Defence Lvl2(20:11)");
//ETC.

然后,我们使用lst1.AddRange(lst2);将两个列表组合成一个新列表:这是输出:

//output of lst1 after the combination
//Armor Lvl1(0:04)
//Loom(0:10)
//Balistics(4:42)
//Mail Armor(5:02)
//Ring(6:12)
//Fire Holes(8:44)
//Attack Lvl2(10:13)
//Defence Lvl1(12:33)
//Defence Lvl2(20:11)
//Attack(1:05)
//MoveUp(1:35)
//MoveDown(1:48)
//MoveLeft(2:15)
//MoveDown(2:24)
//MoveUp(2:50)
//MoveLeft(3:04)
//MoveUp(5:15)
//MoveLeft(7:30)

现在,我需要按时间戳重新排列此组合列表,以便输出看起来像:

//output of lst1 in order by timestamp
Armor Lvl1(0:04)
Loom(0:10)
Attack(1:05)
MoveUp(1:35)
MoveDown(1:48)
MoveLeft(2:15)
MoveDown(2:24)
MoveUp(2:50)
MoveLeft(3:04)
Balistics(4:42)
Mail Armor(5:02)
MoveUp(5:15)
Ring(6:12)
MoveLeft(7:30)
Fire Holes(8:44)
Attack Lvl2(10:13)
Defence Lvl1(12:33)
Defence Lvl2(20:11)

任何线索如何实现此命令?

一些提示:

要从字符串中提取时间戳,请执行以下操作:

Regex.Match("Defence Lvl2(20:11)", @"\(([^)]*)\)").Groups[1].Value;

3 个答案:

答案 0 :(得分:1)

这是没有正则表达式或linq的解决方案。

仅使用老式的手。

    static void Test()
    {
      List<string> list = new List<string>();
      list.Add("Armor Lvl1(0:04)");
      list.Add("Loom(0:10)");
      list.Add("Balistics(4:42)");
      list.Add("Mail Armor(5:02)");
      list.Add("Ring(6:12)");
      list.Add("Fire Holes(8:44)");
      list.Add("Attack Lvl2(10:13)");
      list.Add("Defence Lvl1(12:33)");
      list.Add("Defence Lvl2(20:11)");
      list.Add("Attack(1:05)");
      list.Add("MoveUp(1:35)");
      list.Add("MoveDown(1:48)");
      list.Add("MoveLeft(2:15)");
      list.Add("MoveDown(2:24)");
      list.Add("MoveUp(2:50)");
      list.Add("MoveLeft(3:04)");
      list.Add("MoveUp(5:15)");
      list.Add("MoveLeft(7:30)");
      foreach ( var item in SortTheListByTime(list) )
        Console.WriteLine(item);
    }
    static List<string> SortTheListByTime(List<string> list)
    {
      var result = new List<string>();
      var items = new SortedDictionary<TimeSpan, string>();
      foreach ( string item in list )
      {
        int index;
        int posColon = item.IndexOf(':');
        if ( posColon == -1 ) continue;
        int posStart = -1;
        for ( index = posColon - 1; index >= 0; index-- )
          if (item[index] == '(')
          {
            posStart = index + 1;
            break;
          }
        if ( posStart == -1 ) continue;
        int posEnd = -1;
        for ( index = posColon + 1; index < item.Length; index++ )
          if ( item[index] == ')' )
          {
            posEnd = index - 1;
            break;
          }
        if ( posEnd == -1 ) continue;
        string strTime = item.Substring(posStart, item.Length - posEnd + 2);
        if ( TimeSpan.TryParse(strTime, out var time) )
          if ( !items.ContainsKey(time) )
            items.Add(time, item);
      }
      result.AddRange(items.Values);
      return result;
    }

答案 1 :(得分:1)

解决方案很容易解决您的问题。

如果您使用linq的OrderBy,然后将圆括号之间的字符串解析为TimeSpan,那么事情将很简单

var result = list.OrderBy(x => TimeSpan.Parse(x.Split('(', ')')[1])).ToList();

如果将结果打印到控制台,则输出为

result.ForEach(x => {
    Console.WriteLine(x);
});

Console.ReadLine();

输出:

enter image description here

答案 2 :(得分:-1)

List类型不强制排序,因此将根据插入顺序进行“排序”。如果这些时间戳记是插入对象的时间,那么对它们进行相应的排序是完全合理的。

要实现排序,geing字符串,您需要编写自己的比较方法并调用List.Sort,同时以委托IComparison或在实现{{1}的类中传递此方法}。

由于这样的原因,我强烈建议您考虑将它们作为对象而不是字符串,因为将IComparerstring Name分为两个字段将使使用排序变得简单TimeSpan Timestamp,而不需要通过Regex(x => x.Timestamp)等提取时间戳。