比较和组合类似字符串的列表

时间:2017-08-23 17:27:02

标签: c# list

我有一个字符串列表,我必须多次运行才能尝试减少重复项。

List <string> EventsList = BuildList.Distinct().ToList(); 

这会删除完全副本,但偶尔会出现重复的事件消息,其中包含完全相同的事件的不同变体。

例如:

  

错误代码[123]:[X]目录中的失败。

     

错误代码[123]:[Y]目录失败。

意图是我可以再次比较这些字符串并提出输出:

  

错误代码[123]:[X,Y]目录失败。

由于变化的输入始终在括号中,我创建了

string pattern = @"\[([^\]]+)";
RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.Compiled;
Regex ConsolidatorRegex = new Regex(pattern, options);
BuildList = EventsList;
foreach (string singleEvent in BuildList)
{
    ConsolidatorRegex.Replace(singleEvent, "");
}

认为我可以比较字符串并再次删除重复项。

但现在我被卡住了。我想尽可能保留时间顺序事件的原始顺序,但我无法想出最好的方法。再次运行BuildList.Distinct().ToList();并不能帮助我捕获(通常是多个)已删除的匹配,因此我可以将它们重新添加。

我以为我可以运行一个执行String.Equals方法的循环并将所有匹配放入字典然后将字典与EventsList进行比较,但我无法得到循环的索引为了创建字典密钥。

有没有更好的方法可以解决这个问题?

3 个答案:

答案 0 :(得分:0)

您可以像in the docs所述建立您的赢比较器。

来自文档:

  

要比较自定义数据类型,您需要实现此接口   并为类型提供自己的GetHashCode和Equals方法。

请参阅the docs for that one

答案 1 :(得分:0)

您可以使用LINQ GroupBy函数对字符串进行分组。

var eventListGrouping = BuildList.GroupBy(eventString => ConsolidatorRegex.Replace(eventString, ""));

然后你可以迭代这些组:

foreach(var variation in eventListGrouping) 
{
    // Use variation.Key to find your 'template string'
    // Iterate over variation to find all the string you want to combine
    // You can reuse you regex to extract the values you want to combine
    // Pay attention to adhere to the correct regex match count.
}

有关IGrouping界面的详细信息,请参阅MSDN

答案 2 :(得分:0)

var memo = new Dictionary<int, List<string>>();

var event_list = new List<string> 
    { 
        "Error code [123]: Failure in the [X] directory.",
        "Error code [123]: Failure in the [Y] directory.",
        "Error code [456]: Failure in the [Y] service.",
    };

var pattern = new Regex(@"(code\s\[(?'code'\d+)\]).*\[(?'message'.*)\]");

foreach(var item in event_list)
{       

    var match = pattern.Match(item);
    var code = Int32.Parse(match.Groups["code"].Value);
    var msg = match.Groups["message"].Value;

    var messages = default(List<string>);

    if(!memo.TryGetValue(code, out messages))
        memo.Add(code, messages = new List<string>());

    messages.Add(msg);
}

var directory_errors = from x in memo where x.Key == 123 select x;

foreach(var error in directory_errors)
    Console.WriteLine(string.Format("Error code [{0}]: Failure in the [{1}] directory", error.Key, string.Join(",", from err in error.Value select "'" + err + "'")));

我们的想法是,我们使用类型Dictionary<int, List<string>>的字典,其中键是错误代码(假设为int),值为List<string>。< / p>

对于每个事件,我们使用正则表达式来提取代码和消息,然后我们检查字典以查看是否已经存在与该代码关联的消息列表,如果是这样我们只是添加到列表中,但是如果不,然后我们创建列表并将其添加到字典中(使用错误代码作为键),然后我们添加到列表中。

Rextester Demo