【问题标题】:Cast IEnumerable<Dictionary<string,object>> to a single merged Dictionary C#将 IEnumerable<Dictionary<string,object>> 转换为单个合并的 Dictionary C#
【发布时间】:2021-07-18 17:51:28
【问题描述】:

首先,我有一个如下所示的类:

class Bag
    {
        public string Name { get; set; }
        public int Number { get; set; }
    }

然后我有更大的字典,看起来像这样:

Dictionary<string, List<Bag>> allBags = ParseLinesIntoBags(lines);

现在我想得到一个与上面的字典相同类型的字典,但条件是 List 必须包含一个特定的名称(在我的例子中是“闪亮的金子”)。如果 allBags 具有以下内容,请进一步说明:

 { "black", new List<Bag>() {new Bag("red", 1), new Bag("blue", 2) } },
 { "yellow", new List<Bag>() {new Bag("shiny gold", 1), new Bag("blue", 2) } },
 { "pink", new List<Bag>() { new Bag("blue", 2), new Bag("shiny gold", 3), new Bag("green", 4) } }

因此其他字典应该有:

{ "yellow", new List<Bag>() {new Bag("shiny gold", 1), new Bag("blue", 2) } },
{ "pink", new List<Bag>() { new Bag("blue", 2), new Bag("shiny gold", 3), new Bag("green", 4) } }

。我正在解决的任务来自 AdventOfCode2020 第 7 天 (LINK)。

编辑:(因为原版没有遵循标准。我还删除了我失败的尝试,因为它们离解决方案太远了,只会导致额外的混乱 em>.)

所以目前我有以下代码(特别感谢@AliReza 提供了一个几乎完整的解决方案):

using System.Collections.Generic;
using System.Linq;
namespace Day7
{
    public class Bag
    {
        public string Name { get; set; }
        public int Number { get; set; }
        public Bag(string name, int number)
        {
            Name = name;
            Number = number;
        }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            Dictionary<string, List<Bag>> allBags = new Dictionary<string, List<Bag>>(){
                { "black", new List<Bag>() {new Bag("red", 1), new Bag("blue", 2) } },
                { "yellow", new List<Bag>() {new Bag("shiny gold", 1), new Bag("blue", 2) } },
                { "pink", new List<Bag>() { new Bag("blue", 2), new Bag("shiny gold", 3), new Bag("green", 4) } }};
            string condition = "shiny gold";
            var containerBagsV =from item in allBags
                                from bag in item.Value
                                where bag.Name == condition
                                select new Dictionary<string, List<Bag>>() { { item.Key, item.Value.ToList() } };
        }
    }
}

我想知道现在有什么方法可以强输入 Dictionary insted 并将其留给 var 吗?如果我立即将 var 更改为 Dictionary

Dictionary<string, List<Bag>> containerBagsV = from item in allBags
                                from bag in item.Value
                                where bag.Name == condition
                                select new Dictionary<string, List<Bag>>() { { item.Key, item.Value.ToList() } };

我得到以下编译错误:

严重性代码描述项目文件行抑制状态 错误 CS0266 无法隐式转换类型 'System.Collections.Generic.IEnumerable>>' 到 'System.Collections.Generic.Dictionary>'。显式转换 存在(您是否缺少演员表?)

如果我尝试投射它

Dictionary<string, List<Bag>> containerBagsV = (Dictionary<string, List<Bag>>)(from item in allBags
                                from bag in item.Value
                                where bag.Name == condition
                                select new Dictionary<string, List<Bag>>() { { item.Key, item.Value.ToList() } });

我得到以下异常: System.InvalidCastException: '无法转换类型的对象

'WhereSelectEnumerableIterator2[&lt;&gt;f__AnonymousType02[System.Collections.Generic.KeyValuePair2[System.String,System.Collections.Generic.List1[Day7.Bag]],Day7.Bag],System.Collections.Generic.Dictionary2[System.String,System.Collections.Generic.List1[Day7.Bag]] ]' 输入 'System.Collections.Generic.Dictionary2[System.String,System.Collections.Generic.List1[Day7.Bag]]'。'

【问题讨论】:

  • “它有错误” 不是一个有用的问题陈述。请edit your post 解决问题,包括缺少您遇到的任何错误的完整详细信息,缺少正确的minimal reproducible example,以及缺少清晰、详细的解释到目前为止,您为尝试解决问题所做的工作以及具体您需要什么帮助。
  • 按照您编辑的问题,我认为您正在寻找的是(删除带有 containerBagsV 的行):var filteredDict = allBags.Where(x =&gt; x.Value.Any(bag =&gt; bag.Name == condition)).ToDictionary(y =&gt; y.Key);

标签: c# dictionary


【解决方案1】:

我认为你应该通过这个例子来理解这个想法

    var allBags = new Dictionary<string, List<Bag>>
    {
        { "black", new List<Bag>()  { new Bag("red", 1), new Bag("blue", 2) } },
        { "yellow", new List<Bag>() { new Bag("shiny gold", 1), new Bag("blue", 2) } },
        { "pink", new List<Bag>() { new Bag("blue", 2), new Bag("shiny gold", 3), new Bag("green", 4) } }
    };
    
    var containerBag = from item in allBags
                       from bag in item.Value
                       where bag.Name == "shiny gold"
                       select item;
 // this return yellow and pink records, you can select bag here also if you want

如果你想要一个字典输出:

var containerBag = from item in allBags
                       from bag in item.Value
                       where bag.Name == "shiny gold"
                       select new Dictionary<string, List<Bag>>() { { item.Key, item.Value.ToList() } }; 

更新 合并版本:

var containerBag = from item in allBags
                       from bag in item.Value
                       where bag.Name == "shiny gold"
                       select item;   

Dictionary<string, List<Bag>> mergedDictionary = new(containerBag);

【讨论】:

  • 虽然这基本上解决了我的问题,但有没有办法强类型我的字典或它必须保持为 var?当我将 Dictionary> insted of var 放入时,它不会让我编译(错误 CS0266),如果我投射它,我也会得到类似的错误
  • 你不能这样做,因为返回对象不是一个字典(例如上面的示例返回 2 个字典),所以它是一个IEnumerable of you dictionary。但如果需要,您可以将两个字典合并为一个。
  • 我添加了一个合并字典示例。 @LukaMrko。如果您不使用 c# 9 > 将 new(containerBag) 更改为 new Dictionary&lt;string, List&lt;Bag&gt;&gt; (containerBag)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-22
  • 1970-01-01
相关资源
最近更新 更多