C#多数组关键词全匹配筛选问题:求助正确实现方向
如何实现主表关键词在关联表中全匹配的筛选逻辑
需求说明
有多张数据表,当table1的所有关键词在table2、table3等其他关联表中均匹配时,将table1的记录存入matched集合;否则存入unmatched集合。
为简化测试场景,用以下数组模拟:
arrayMain:模拟table1,每个元素用&作为分隔符拆分关键词arrayData1、arrayData2:模拟两张关联表,两者长度一致,对应索引的元素为一组关联数据(比如arrayData1存员工姓名,arrayData2存对应地址)
现有测试代码
// 固定长度约1000 string[] arrayMain = { "some&set&of&string&with&Ampersent&As&Delimeter", "other&set&of&string&with&Ampersent&As&Delimeter", "another&set&of&string&with&Ampersent&As&Delimeter", // ... 更多元素 }; // 长度比arrayMain大,约3000-4000 string[] arrayData1 = { "some set of string, with special characters, numbers and more.,", "next set of string, may have special characters, numbers and more.", "another set strings, with special characters, numbers and more.,", // ... 更多元素 }; // 长度与arrayData1一致 string[] arrayData2 = { "some set of string, with special characters, numbers and more.,", "next set of string, may have special characters, numbers and more.", "another set strings, with special characters, numbers and more.,", // ... 更多元素 }; List<string> matched = new List<string>(); List<string> unMatched = new List<string>(); foreach (string str in arrayMain) { // 拆分主字符串的关键词,用于和关联表字符串逐一比对 string[] mainSplit = str.Split('&'); bool isMatched = false; for (int i = 0; i < arrayData1.Length; i++) { // 预期逻辑:如果arrayData1[i]和arrayData2[i]包含mainSplit的所有关键词,则加入matched集合 if (mainSplit.Any(s => s.IndexOf(arrayData1[i], StringComparison.CurrentCultureIgnoreCase) > -1) && mainSplit.Any(s => s.IndexOf(arrayData2[i], StringComparison.CurrentCultureIgnoreCase) > -1)) { matched.Add(str); isMatched = true; break; } } if (!isMatched) unMatched.Add(str); }
预期逻辑示例
// 主元素拆分后的关键词数组 string[] mainSplit = {"some", "example", "string", "here" }; // 某一组关联数据 string arrayData1_i = "some other string"; string arrayData2_i = "other example string here";
此例中,arrayData1_i和arrayData2_i的合并内容包含mainSplit的所有关键词,属于100%全匹配,应将对应的主元素存入matched列表。
现有代码的问题
- 匹配逻辑颠倒:现有代码判断的是
mainSplit的元素是否包含arrayData1[i]/arrayData2[i],但实际需要判断的是arrayData1[i]/arrayData2[i]是否包含mainSplit的关键词 - 未实现全匹配检查:用
Any()只检查了是否存在至少一个关键词匹配,而非所有关键词都匹配 - 关联数据未合并检查:代码要求
arrayData1[i]和arrayData2[i]各自至少匹配一个关键词,但实际需要的是两组关联数据的合并内容覆盖所有主关键词
正确实现思路与代码
优化点
- 预处理关联数据:将
arrayData1和arrayData2对应位置的内容合并,拆分为关键词集合(用HashSet提升查询效率) - 对每个主元素,拆分出关键词集合
- 检查是否存在某一组关联数据的关键词集合,包含主元素的所有关键词
修改后的代码
using System.Linq; using System.Collections.Generic; // 预处理关联数据:将arrayData1和arrayData2对应位置的内容合并,拆分为不区分大小写的关键词HashSet var dataSets = arrayData1.Zip(arrayData2, (d1, d2) => $"{d1} {d2}") .Select(content => new HashSet<string>( content.Split(new[] {' ', ',', '.'}, StringSplitOptions.RemoveEmptyEntries), StringComparer.CurrentCultureIgnoreCase ) ).ToList(); List<string> matched = new List<string>(); List<string> unMatched = new List<string>(); foreach (string str in arrayMain) { string[] mainKeywords = str.Split('&'); bool isFullyMatched = false; foreach (var dataSet in dataSets) { // 检查主元素的所有关键词是否都在当前关联数据集合中 if (mainKeywords.All(keyword => dataSet.Contains(keyword))) { matched.Add(str); isFullyMatched = true; break; } } if (!isFullyMatched) unMatched.Add(str); }
补充说明
- 如果关联数据的关键词拆分规则(比如分隔符)和主元素不同,可以根据实际需求调整
Split的参数 - 使用
HashSet是因为其Contains方法的时间复杂度为O(1),比直接用字符串IndexOf效率更高,适合处理大数量级的数据 - 如果需要更精确的匹配(比如完整单词匹配,而非子串匹配),上述拆分+HashSet的方式比
IndexOf更可靠,避免部分匹配的问题
内容的提问来源于stack exchange,提问作者StackUseR
相关产品推荐
相关产品推荐

