我有一个字典,其中键是枚举值列表,值是一个简单的字符串。
我需要做的是使用另一个枚举值列表找到匹配的 KVP。
在这里发布的曲线球和原因是,如果我的测试或搜索列表中的列表包含字典中任何键中的所有项目(或枚举对象),我还需要它返回 KVP。
示例代码摘录:
public enum fruit{ apple , orange , banana , grapes };
public class MyClass
{
public Dictionary<List<fruit>, string> FruitBaskets = new Dictionary<List<fruit>, string>;
FruitBaskets.Add(new List<fruit>{apple,orange},"Basket 1");
List<fruit> SearchList = new List<fruit>{orange,apple,grapes};
}
我需要在字典中搜索
SearchList
并返回“Basket 1”。请注意,匹配可能比您对这样的示例所期望的要倒退,因为我需要关键字来再次匹配搜索列表,反之亦然,因此搜索列表中不在关键字中的额外项目是可以的。
我知道我可以简单地迭代字典并一个一个地检查,但我也需要它尽可能快,因为它驻留在运行相当快的循环中。
我目前使用的是;
public Dictionary<List<fruit>, string> SearchResults;
foreach (KeyValuePair<List<fruit>, string> FruitBasket in FruitBaskets)
{
if (FruitBasket.Key.Except(SearchList).Count() == 0)
SearchResults.Add(FruitBasket);
}
想知道是否有更好/更快的方法。
最佳答案
您需要重新考虑在字典中选择键。 List 键存在一些主要问题,例如:
var a = new[] { fruit.organge }.ToList();
var b = new[] { fruit.organge }.ToList();
fruitBasket.Add(a, "1");
fruitBasket.Add(b, "2");
但是这本字典有效吗?我想不是,但这取决于您的要求。
出于这个原因,您需要更改您的字典键类型。您可以使用组合的 Enum 值,而不是使用带有按位运算符的 List。为此,您需要为每个枚举值分配 2 的幂:
[Flags]
public Enum Fruit
{
Orange = 1,
Apple = 2,
Banana = 4,
Grape = 8
}
您必须组合这些枚举值才能获得所需的多值枚举字典键效果:
对于
[Fruit.Orange, Fruit.Apple]
您使用 Fruit.Orange | Fruit.Apple
。这是用于组合和分解值的示例代码:
private static fruit GetKey(IEnumerable<fruit> fruits)
{
return fruits.Aggregate((x, y) => x |= y);
}
private static IEnumerable<fruit> GetFruits(fruit combo)
{
return Enum.GetValues(typeof(fruit)).Cast<int>().Where(x => ((int)combo & x) > 0).Cast<fruit>();
}
现在您需要一个函数来获取 SearchList 的所有组合(幂集):
private static IEnumerable<fruit> GetCombinations(IEnumerable<fruit> fruits)
{
return Enumerable.Range(0, 1 << fruits.Count())
.Select(mask => fruits.Where((x, i) => (mask & (1 << i)) > 0))
.Where(x=>x.Any())
.Select(x=> GetKey(x));
}
使用这些组合,您可以使用 O(1) 时间从字典中查找值。
var fruitBaskets = new Dictionary<fruit, string>();
fruitBaskets.Add(GetKey(new List<fruit> { fruit.apple, fruit.orange }), "Basket 1");
List<fruit> SearchList = new List<fruit> { fruit.orange, fruit.apple, fruit.grapes };
foreach (var f in GetCombinations(SearchList))
{
if (fruitBaskets.ContainsKey(f))
Console.WriteLine(fruitBaskets[f]);
}
关于c# - 从 Dictionary<List<enum>,string> 中查找匹配的 KVP,其中搜索键是 List<enum> 并返回反向部分匹配,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26439761/