提取共享值的Key组合:现有代码无法生成1/3个Key的组合
解决:生成所有共享整数列表值的Key组合
嘿,我来帮你搞定这个问题!你现在需要生成所有共享整数列表值的Key组合,包括单个、两个甚至三个Key的情况,但之前的多层foreach只能处理两两组合,还漏了不少情况对吧?先理清楚你的需求和现有问题:
你有一个Dictionary,Key是字符串,Value是整数列表,需要生成所有存在共享整数的Key组合,包括1个、2个、3个Key的情况,预期输出是:
["A","B","C"] //1是公共值 ["A","B"] //1、2、3是公共值 ["B","C"] //1、4是公共值 ["C"] //5是专属值
而你之前的多层foreach循环只能生成2个Key的组合,还漏了单个Key和三个Key的情况,同时还有重复添加组合的问题。
你的输入代码
var keyCombos = new List<List<string>>(); var dict = new Dictionary<string, List<int>>(); dict.Add("A", new List<int>() { 1, 2, 3 }); dict.Add("B", new List<int>() { 1, 2, 3, 4 }); dict.Add("C", new List<int>() { 1, 4, 5 });
解决方案代码
我给你写了一套完整的实现,能覆盖所有你需要的组合情况:
var keyCombos = new List<List<string>>(); var dict = new Dictionary<string, List<int>>(); dict.Add("A", new List<int>() { 1, 2, 3 }); dict.Add("B", new List<int>() { 1, 2, 3, 4 }); dict.Add("C", new List<int>() { 1, 4, 5 }); // 第一步:生成所有大小>=2的Key组合,且它们存在公共整数 var allKeys = dict.Keys.ToList(); for (int size = 2; size <= allKeys.Count; size++) { // 生成当前大小的所有Key组合 var combinations = GetCombinations(allKeys, size); foreach (var combo in combinations) { // 计算组合中所有Key的整数列表的交集 var commonValues = dict[combo.First()].ToList(); foreach (var key in combo.Skip(1)) { commonValues = commonValues.Intersect(dict[key]).ToList(); if (!commonValues.Any()) break; // 没有交集就提前终止 } // 如果有公共值,且该组合未被添加过,就加入结果 var sortedCombo = combo.OrderBy(k => k).ToList(); if (commonValues.Any() && !keyCombos.Any(c => c.OrderBy(k => k).SequenceEqual(sortedCombo))) { keyCombos.Add(sortedCombo); } } } // 第二步:处理单个Key的情况(仅当该Key有专属整数时) foreach (var key in allKeys) { var values = dict[key]; // 检查是否存在某个整数,其他所有Key的列表都不包含它 bool hasExclusiveValue = values.Any(v => allKeys.Where(k => k != key).All(k => !dict[k].Contains(v))); if (hasExclusiveValue) { keyCombos.Add(new List<string>() { key }); } } // 辅助方法:生成列表的所有指定大小的组合 static IEnumerable<IEnumerable<T>> GetCombinations<T>(IEnumerable<T> list, int length) { if (length == 1) return list.Select(t => new T[] { t }); return GetCombinations(list, length - 1) .SelectMany(t => list.Where(e => !t.Contains(e)), (t1, t2) => t1.Concat(new T[] { t2 })); } // 打印结果验证 foreach (var combo in keyCombos) { var commonVals = dict[combo[0]].ToList(); foreach (var key in combo.Skip(1)) { commonVals = commonVals.Intersect(dict[key]).ToList(); } Console.WriteLine($"[{string.Join(",", combo.Select(k => $"\"{k}\""))}] // {string.Join(",", commonVals)}是公共值"); }
代码说明
- 组合生成:用
GetCombinations辅助方法生成所有指定大小的Key组合,避免了手动写多层foreach的繁琐,能轻松支持2个、3个甚至更多Key的组合; - 交集检查:对每个组合,计算所有Key的整数列表的交集,只有交集非空的组合才会被加入结果;
- 去重处理:通过排序后比较的方式,避免添加重复的组合;
- 单个Key处理:只添加那些有专属整数的单个Key(比如C的5,其他Key都没有),符合你的预期输出要求。
运行这段代码后,就能得到你想要的所有组合啦!
内容的提问来源于stack exchange,提问作者chillydk147
相关产品推荐
相关产品推荐

