我正在尝试在每个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 });
上面是一个字典,其中包含一个字符串Key和一个整数列表作为其值,keyCombos
列表将包含共享整数列表值的所有键组合,keyCombos
的预期输出将低于
["A","B","C"] //1 is common
["A","B"] //1,2,3 are common
["B","C"] //1,4 are common
["C"] //5
组合的顺序并不重要,到目前为止我的代码使用了各种foreach
循环,我只能组合2个密钥,而不是1个或3个。
foreach(var k1 in dict.Keys)
{
List<int> a1 = dict[k1];
foreach (var k2 in dict.Keys)
{
if (k1 != k2)
{
List<int> a2 = dict[k2];
if(a1.Intersect(a2).Count()>0)
{
var matches = false;
foreach(var combo in keyCombos)
{
if ((combo.Contains(k1)) && (combo.Contains(k2)))
{
matches = true;
}
}
if (!matches)
{
keyCombos.Add(new List<string>() { k1, k2 });
}
}
else
{
keyCombos.Add(new List<string>() { k1 });
}
}
}
}
答案 0 :(得分:2)
使用linq你可以这样做
AnonymousComparer
keyCombos = dict.SelectMany(g => g.Value.Select(k => new { Key = g.Key, Value = k })).GroupBy(g => g.Value, (key, group) => group.Select(g => g.Key).ToList()).Distinct(AnonymousComparer.Create((List<string> mc) => string.Join(";", mc))).ToList();
是用于创建IEqualityComparer的类。它来自
AnonymousComparer nuget包。
或者就是这样
SelectMany
首先,使用 $(function () {
$("#datepicker").datepicker({
onSelect: function () {
$('#sched_macs_button').show(300);
},
dateFormat: 'yy-mm-dd',
changeMonth: true,
beforeShowDay: $.datepicker.noWeekends,
numberOfMonths: 1,
minDate: dateToday
});
});
我们从字典中的值中排除列表,并获取具有重复键的所有键值对。
之后我们只按值组合这个新集合并从组中选择键。最后,我们按值选择唯一的组。
答案 1 :(得分:2)
我只想澄清一下,你想要返回所有传递的“键”之间“共同/交叉”的元素吗?
如果是[“A”,“B”],则不应该只使用1,2,3而不是2,3。如果是,请在问题陈述中更新。
在[“C”]的情况下,由于只有一个键,所以不应该有共同点。正确的吗?
如果是,那么您应该尝试以下内容:
public List<int> FindIntersection(string[] keys, Dictionary<string, List<int>> dict)
{
if(keys.Length <= 1)
{
return null;
}
HashSet<int> commonElements = new HashSet<int>();
dict[keys[0]].ForEach(x => commonElements.Add(x));
for(int i = 1; i < keys.Length; i++)
{
commonElements.IntersectWith(dict[keys[i]]);
}
return commonElements.ToList();
}
答案 2 :(得分:1)
我认为最简单的方法是首先从字典中获取不同的整数,然后遍历它们并使用linq获取该整数在列表中的键。喜欢:
var distinctKeyCombos = dict.SelectMany(x => x.Value).Distinct();
foreach(var i in distinctKeyCombos)
{
var keys = dict.Where(p => p.Value.Contains(i)).Select(p => p.Key);
}
答案 3 :(得分:0)
您可以使用SelectMany和GroupBy在LINQ中执行此操作:
var pivot = dict.SelectMany(kv => kv.Value.Select(v => new {v, kv.Key}))
.GroupBy(x => x.v);
组的键将是int值,其内容将是包含值和字母的匿名类型。
首先将每个字母与一对中的int值配对(你也可以在这里使用System.ValueTuple而不是匿名类型)。然后它将列表列表展平为单个列表,最后按int值对它们进行分组。
不是将值存储在字典中,而是将它们存储为简单对(“A”,1),...然后您可以轻松地以任一方式检索它们:按字母分组或按int分组。