我要查找什么数据结构?


Dictionary<List<string>, string> myDictionary = new Dictionary<List<string>, string>
{
{ new List<string> { "blackberries", "orange", "watermelon", "apple" }, "fruits" },
{ new List<string> { "spinach", "kale", "celery", "tomato", "red onion" }, "veggies" },
{ new List<string> { "almonds", "walnuts", "fish oil", "nut butter" }, "fats" },
{ new List<string> { "oatmeal", "brown rice", "beans", "lentils" }, "carbs" },
{ new List<string> { "beef", "chicken", "eggs", "salmon", "mackerel" }, "proteins" },
};

用例是打入一个字符串,看看它存在于哪个键中,然后吐出它的正确值。前任:

var temp = myDictionary[new List<string> { "beans" }];

温度返回碳水化合物。

尽管目前的结构方式是这样,但这不起作用,因为"豆子"不作为key存在,而是作为key的一部分存在。

哪种结构最适合这种类型的数据使用?

">

beans"应该是一个键,"carb"是值。 键应该是简单的类型,值可能很复杂。 在你的情况下,它不应该是。 只需使用字典,其中食物是关键,食物类型是值。 您不必在键中搜索即可查找与它关联的值。 在您的示例中,您必须遍历所有键,然后搜索哪个键匹配,然后获取值。 这违背了拥有钥匙的目的。

翻转它,使食物类型是查找食物列表的关键,然后构建一个字典,您可以在其中根据食物查找食物类型。

是的,LINQ 可以做各种奇妙的事情,但除非你正确地构建东西,否则到达那里会很慢。 这是在任一方向上查找所需内容的最快方法。

var myDictionary = new Dictionary<string, List<string>>
{
{ "fruits", new List<string> { "raspberries", "blackberries", "blueberries", "orange", "watermelon", "apple", "strawberries" } },
{ "veggies", new List<string> { "spinach", "kale", "carrots", "celery", "tomato", "red onion" } },
{ "fats", new List<string> { "almonds", "walnuts", "fish oil", "nut butter" } },
{ "carbs",new List<string> { "oatmeal", "brown rice", "beans", "lentils" } },
{ "proteins", new List<string> { "beef", "chicken", "eggs", "salmon", "mackerel" } },
};
var myFoodIndex = new Dictionary<string, string>();
foreach(var key in myDictionary.Keys)
{
foreach (var foodType in myDictionary[key])
myFoodIndex.Add(foodType, key);
}
Console.WriteLine(myFoodIndex.ContainsKey("beans") ? myFoodIndex["beans"] : "Not Found");
Console.ReadKey();

我应该补充一点,如果你想对列表进行排序,请使用 SortedDictionary 或 SortedList。 在此处阅读有关每种方法的优缺点的更多信息。

var myItems = new Tuple<List<string>, string>[]
{
new Tuple<List<string>, string>(new List<string> { "raspberries", "blackberries", "blueberries", "orange", "watermelon", "apple", "strawberries" }, "fruits" ),
new Tuple<List<string>, string>(new List<string> { "spinach", "kale", "carrots", "celery", "tomato", "red onion" }, "veggies" ),
new Tuple<List<string>, string>(new List<string> { "almonds", "walnuts", "fish oil", "nut butter" }, "fats" ),
new Tuple<List<string>, string>(new List<string> { "oatmeal", "brown rice", "beans", "lentils" }, "carbs" ),
new Tuple<List<string>, string>(new List<string> { "beef", "chicken", "eggs", "salmon", "mackerel" }, "proteins" ),
};
var myDictionary = myItems.SelectMany(t => t.Item1.Select(item => new {item, type = t.Item2}))
.ToDictionary(a => a.item, a => a.type);
Console.WriteLine(myDictionary["spinach"]);

由于Dictionary<TKey, TValue>实现了IEnumerable<KeyValuePair<TKey, TValue>>因此可以使用 LINQ 对数据进行操作。

在这种情况下,您的键是List<string>的,List.Contains将允许您检查列表中是否有字符串。 找到匹配的条目后,您只需抓取该对中的Value成员即可。 由于KeyValuePair<>是一种值类型,因此您不必担心FirstOrDefault的 null 返回,因此让我们使用它:

var value = myDictionary.FirstOrDefault(kv => kv.Key.Contains("beans")).Value;

如果未找到您要搜索的字符串(在本例中为"bean"(,则输出将为 null。

至于数据结构...

Dictionary<List<string>, string>是一个奇怪的选择。 除了开销之外,您几乎无法从对象中获得任何东西。 你不能使用Dictionary<>方法来获取数据,你的"键"不容易搜索,等等。

对于带有少量装饰以便于阅读的普通存储,您可以使用新ValueTuple<>类的数组,如下所示:

(string Category, string[] Items)[] foods = new[] {
("fruits", new[] { "raspberries", "blackberries", "blueberries", "orange", "watermelon", "apple", "strawberries" }),
( "veggies", new[] { "spinach", "kale", "carrots", "celery", "tomato", "red onion" }),
( "fats", new[] { "almonds", "walnuts", "fish oil", "nut butter" }),
( "carbs", new[] { "oatmeal", "brown rice", "beans", "lentils" }),
( "proteins", new[] { "beef", "chicken", "eggs", "salmon", "mackerel" }),
};

这是一个包含一些编译时内容的数组,以使其更易于访问。 查找基本相同:

var value = foods.FirstOrDefault(_ => _.Items.Contains("beans")).Category;

这只是许多方法中的一种。 如果没有关于您的实际用例的更多信息,您可以采取太多方法。

最新更新