我要寻找什么数据结构?

时间:2018-08-22 22:27:16

标签: c# string list dictionary data-structures

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" }];

温度返回碳水化合物。

尽管当前的结构方式如此,但它不能工作,因为{beans}不存在,keykey的一部分。

哪种类型最适合此类数据使用?

3 个答案:

答案 0 :(得分:2)

“ beans”应为键,“ carb”为值。密钥应该是简单类型,其值可能很复杂。在您的情况下都不应该。只需使用字典,其中食物是关键,食物的类型就是价值。您不必在键内搜索即可找到与之关联的值。在您的示例中,您必须遍历所有键,然后搜索匹配的键,然后获取值。这破坏了拥有钥匙的目的。

翻转它,以便食物类型成为找到食物清单的关键,然后构建一个Dictionary,您可以在其中基于食物查找食物类型。

是的,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。详细了解here各自的优点和缺点。

答案 1 :(得分:0)

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"]);

答案 2 :(得分:0)

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

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

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

如果未找到要搜索的字符串(在这种情况下为“ beans”),则输出将为空。

关于数据结构...

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;

许多方法中的只有一种。如果没有有关实际用例的更多信息,您将有太多的选择。