选择的水果 ="banana,banana,cherry,kiwi,strawberry"
lookup List<string>
"banana,strawberry" (true)
"strawberry" (true)
"banana,banana,banana" (false)
如果查找中仅与所选项目的一部分完全匹配,则应在结果中选择该项目。
最好的方法是什么?
问题只是将每个项目转换为一个袋子,然后测试袋子的密封性:
private IDictionary<string, int> StringToBag(string str)
{
return str.Split(',').GroupBy(s => s).ToDictionary(g => g.Key, g => g.Count());
}
private bool BagContains(IDictionary<string, int> haystack, IDictionary<string, int> needle)
{
return needle.All(kv => haystack.ContainsKey(kv.Key) && kv.Value <= haystack[kv.Key]);
}
var bag = StringToBag("banana,banana,cherry,kiwi,strawberry");
bool contained = BagContains(bag, StringToBag("banana,strawberry"));
如果您的对象是这样初始化的:
string selected = "banana,banana,cherry,kiwi,strawberry";
List<string> lookup = new List<string>()
{
"banana,strawberry",
"strawberry",
"banana,banana,banana"
};
你有一个这样的分组方法:
Dictionary<string, int> ToGroupDictionary(string value)
{
return value.Split(',')
.GroupBy(s => s.Trim())
.ToDictionary(g => g.Key, g => g.Count());
}
你可以像这样测试每个字符串lookup
:
var selectedDictionary = ToGroupDictionary(selected);
// ["banana", 2]
// ["cherry", 1]
// ["kiwi", 1]
// ["strawberry", 1]
foreach(string test in lookup)
{
var testDictionary = ToGroupDictionary(test);
testDictionary.Keys.ToList().ForEach(k =>
Console.WriteLine(selectedDictionary.ContainsKey(k) &&
selectedDictionary[k] >= testDictionary[k]));
// [0] :=
// ["banana", 1]
// ["strawberry", 1]
// true, banana and strawberry exist
// [1] :=
// ["strawberry", 1]
// true, strawberry exists
// [2] :=
// ["banana", 3]
// false, too many bananas
}
看一下这个:
private static void LoadFruits(string Fruit, Dictionary<string, int> FruitDictionary)
{
if (FruitDictionary.ContainsKey(Fruit))
FruitDictionary[Fruit] = FruitDictionary[Fruit] + 1;
else
FruitDictionary.Add(Fruit, 1);
}
private static bool HasFruit(string Fruit, Dictionary<string, int> FruitDictionary)
{
if (FruitDictionary.ContainsKey(Fruit) && FruitDictionary[Fruit] > 0)
{
FruitDictionary[Fruit] = FruitDictionary[Fruit] - 1;
return true;
}
return false;
}
...
List<string> AllThefruits = new List<string>(){"banana" ,"banana","cherry","kiwi","strawberry"};
Dictionary<string, int> FruitsDictionary = new Dictionary<string, int>();
List<string> Combination1 = new List<string>() { "banana", "strawberry" };
AllThefruits.ForEach(x => LoadFruits(x, FruitsDictionary));
bool TestCombination1 = Combination1.All(x => HasFruit(x, FruitsDictionary)); //true
FruitsDictionary.Clear();
List<string> Combination2 = new List<string>() { "strawberry" };
AllThefruits.ForEach(x => LoadFruits(x, FruitsDictionary));
bool TestCombination2 = Combination2.All(x => HasFruit(x, FruitsDictionary)); //true
FruitsDictionary.Clear();
List<string> Combination3 = new List<string>() { "banana", "banana", "banana" };
AllThefruits.ForEach(x => LoadFruits(x, FruitsDictionary));
bool TestCombination3 = Combination3.All(x => HasFruit(x, FruitsDictionary)); //false
FruitsDictionary.Clear();
List<string> Combination4 = new List<string>() { "banana", "banana" };
AllThefruits.ForEach(x => LoadFruits(x, FruitsDictionary));
bool TestCombination4 = Combination4.All(x => HasFruit(x, FruitsDictionary)); //true
但是,我不确定这是否是最佳解决方案。
public static bool CheckCombination(List<string> values, List<string> combinations)
{
var valuesLookup = values.ToLookup(x => x);
return CheckCombination(valuesLookup, combinations);
}
public static bool CheckCombination(ILookup<string, string> valuesLookup, List<string> combinations)
{
foreach (var combination in combinations.GroupBy(x => x))
{
if (valuesLookup.Contains(combination.Key) &&
valuesLookup[combination.Key].Count() < combination.Count())
return false;
}
return true;
}
未经测试,但这是否可行:
string fr = "banana,banana,cherry,kiwi,strawberry";
IList<string> selFr = fr.Split(new string[] { "," }, StringSplitOptions.None);
IList<string> look = new List<string>();
// Add the lookup values to the "look" list here...
IList<string> res = new List<string>();
foreach (string lookupStr in look) {
foreach (string f in selFr) {
if (lookupStr.Contains(f)) {
res.Add(lookupStr);
continue;
}
}
}
return res;