如何创建由字母和数字组成的一系列字符串组合?

4

我有一个数据列表集合,例如:

List<String> Dummy = new List<String>()
{
  "1001A",
  "1003A",
  "1002B",
  "1002A",
  "1003B",
  "1001B",
  "1003C",
  "1002C",
  "1001C",
};

我希望把这个数据列表按照一定规律排列成系列。主系列将以字母(字符串的最后一个字符)为重点,而子系列将基于剩余的数字。输出结果应该如下:

1001A
1002A
1003A
1001B
1002B
1003B
1001C
1002C
1003C

除了上面的例子之外,我已经有了一系列数字的功能代码。感谢阅读我的帖子。

4个回答

7
 var result = Dummy
              .OrderBy(p => p[p.Length - 1])
              .ThenBy(p => p.Substring(0, p.Length - 1));

这将首先按字符串的最后一个字符排序,然后按除字符串的最后一个字符以外的所有内容排序。

如果所有字符串的长度相同,则可以将最后一部分留在 .ThenBy(p => p),因为字符串已经按最后一个字符排序。但如果字符串长度不同,则需要像我的代码中那样使用子字符串。


如果所有字符串的长度与 OP 示例中相同,则此方法有效,但如果字符串长度不同,则会将“1001A”放在“200A”之前。 - juharr
2
@juharr 没错,我认为这就是作者想要的。比如说文件名。如果纯粹是数字,他需要使用 int.Parse(p.Substring(0, p.Length - 1)) - LInsoDeTeh

2
如果字符串的长度可能不同,则需要以下操作。
var result = data.OrderBy(d => d[d.Length - 1])
                 .ThenBy(d => int.Parse(d.Substring(0, d.Length - 1])));

当然,您需要防范可能出现的解析异常情况。

这假定您希望“200A”排在“1000A”之前。


感谢您的帮助,先生。我看到您只有一行代码来完成这个函数,但对我来说需要很多行。再次感谢您,先生。 - Bad Idea

1

版本 a)(最快)

使用内置的 Sort 方法(就地排序),并带有自定义的 Comparision 委托/lambda。

 dummy.Sort((s1, s2) =>
 {
      // TODO: Handle null values, now supposing s1 and s2 are not null
      // TODO: Handle variable length if needed. Supposing fixed 4+1 data 
      var result = s1[4].CompareTo(s2[4]);
      if (result != 0)
      {
          return result;
      }
      return s1.Substring(0, 4).CompareTo(s2.Substring(0, 4));
  });

为了重复使用比较器,您可以将其编写为静态方法而不是内联lambda表达式,但在这种情况下,我建议实现IComparator。(Sort方法有一个接受IComparator的重载)

b版本:

使用LINQ:

// TODO: Handle variable length if needed, supposing fixed 4+1 data structure:
var orderedList = dummy.OrderBy(s => s[4]).ThenBy(s => s.SubString(0,4).ToList();

1
如果字符串长度不同,这会导致“索引超出范围异常”。 - fubo

1
一种基于分组的解决方案:
var res = Dummy.GroupBy(str => str.Last()).OrderBy(g => g.Key)
               .SelectMany(g => g.OrderBy(str => str.Substring(0, str.Length - 1)))
               .ToList();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接