在列表中对项目进行排序/分组

时间:2016-09-27 14:42:08

标签: c# list group-by

我有一个文件名列表,看起来像这样:

SAN003A-S6cp-201607221655.SSHOW_SYS.tgz

SAN003A-S7cp-201607221655.SSHOW_SYS.tgz

BrocadeRK4-S4cp-201604140110.SSHOW_SYS.tgz

BrocadeRK4-S5cp-201604140110.SSHOW_SYS.tgz

共同点是' SNcp'模式,其中N是数字。之前和之后的内容可能有所不同。它是网络交换机的机器生成输出。我可以在列表中有1,2或更多。我可以处理1或2.要么意味着它们来自同一个开关。来自同一交换机的文件将在' SNcp'之前和之后匹配。如果超过2则表示来自多个交换机的日志混合在同一文件夹中。上面的例子有2个开关。我需要能够根据“SNcp”之前的内容进行排序/和/或分组。图案。我想我需要一个正则表达式,但是当我通过正则表达式搜索分组列表时,我得到了如何命名组。所以我不确定GroupBy的谓词应该是什么。 ' SNcp'的起始位置模式也会有所不同,所以我不确定如何进行子串。

2 个答案:

答案 0 :(得分:0)

所以,为了可靠地做到这一点,你需要操纵这样一个事实,事实上,你知道有各种各样的模式和理由。我假设这里的排序是A-Z下降。有一些通用的算法:

Create a Dictionary<String, List<File>>.
FOREACH File
   collect the first substring (0 to the first -)
   try to add the file to the dictionary using the substring as a key
      if it works, go to the next one
   Catch if the Key doesn't exist
      add the substring to the dictionary as a key with a new list
      add the file to the dictionary using the new key.
end FOREACH
FOREACH key in the dictionary
  sort the list alphabetically
end FOREACH

因此,字典非常擅长按通用性对事物进行分组,你已经明白的是Switch键(SNc)或左侧的名称(SAN3000A等)。我们可以这样做,因为所有潜在文件都有一个共同的分隔符( - ),所以我可以可靠地“猜测”我的密钥来自哪里。

答案 1 :(得分:0)

所以,如果我理解正确,你想做什么,它对你有用:

var files = new[]
{
    "SAN003A-S6cp-201607221655.SSHOW_SYS.tgz",
    "SAN003A-S7cp-201607221655.SSHOW_SYS.tgz",
    "BrocadeRK4-S4cp-201604140110.SSHOW_SYS.tgz",
    "BrocadeRK4-S5cp-201604140110.SSHOW_SYS.tgz"
};

var regex = new Regex("-(S[0-9]+cp)-", RegexOptions.Compiled);
var grouped = files.GroupBy(x => regex.Match(x).Groups[1].Value);
if (grouped.Any(x => x.Count() > 2))
{
    //  logs from multiple switches are mixed in the same folder
}