首页 > 解决方案 > 比较 2 个列表数据与部分匹配并从两个列表返回聚合数据

问题描述

我有以下 2 个列表,我需要将masterData's NamesampleData's Name进行部分匹配,并且需要输出NamefromMasterVersionfrom SampleData。( Name_version)

var masterData = new List<Master>
{
    new Master{Name = "Master1"},
    new Master{Name = "Master2"},
    new Master{Name = "Master3"},
    new Master{Name = "Master4"}
};

var sampleData = new List<SampleData>
{
    new SampleData{Name = "this is master1", Version = "20.01"},
    new SampleData{Name = "this is master1", Version = "20.02"},
    new SampleData{Name = "this is master3", Version = "23.01"},
    new SampleData{Name = "this is master5", Version = "20.01"}
};

当有部分匹配时正在寻找的Name预期MasterVersionSampleData输出。

 var output = new List<SampleData>
{
    new SampleData{Name = "Master1_20.01"}, 
    new SampleData{Name = "Master1_20.02"},
    new SampleData{Name = "Master3_23.01"}
};

我尝试直到部分匹配,我为所有Master数据准备了一个长字符串“|” 分隔符,但无法弄清楚如何准备我想要的输出。

var regexPattern = masterData.Aggregate(string.Empty, (current, md) => current + $"{md.Name}|");

var output = (from data in sampleData
    let IsMatched = Regex.IsMatch(data.Name, regexPattern.TrimEnd('|'), RegexOptions.IgnoreCase)
    where IsMatched
         select data).ToList();

标签: c#linq

解决方案


这是一个没有正则表达式的解决方案:

var output = 
    sampleData.Select(sd =>
    {
        var master = masterData.FirstOrDefault(m => sd.Name.ContainsIgnoreCase(m.Name));
        return (master is null ? null
                : new SampleData { Name = $"{master.Name}_{sd.Version}" });
    })
    .Where(sd => sd != null)
    .ToList();

ContainsIgnoreCase()如下所示的扩展方法在哪里:

public static class StringExtensions
{
    public static bool ContainsIgnoreCase(this string s, string value)
    {
        return (s.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0);
    }
}

在线演示


推荐阅读