C# - 如何遍历字典,其中键是 Int,值是列表,并根据条件,添加到列表或创建新条目

时间:2021-06-27 20:08:28

标签: c# linq

此方法接受一个体量列表,并尝试根据它们的 X 和 Y 属性对它们进行分组。我试图通过创建一个名为 Dictionary<int, List<Massing>> 的字典 buildingList 来做到这一点,如果迭代中的当前 Massing 对象具有相同的X 和 Y 属性作为 List<Massing> 对象已经在 Massing 中,如果不是,我会使用累积的 Massing 创建一个新的字典条目。

我遇到的错误是 buildingList。根据我的浅薄理解,我认为出现此问题是因为我试图通过在运行时向值列表添加更多项来更改值列表。

我不确定这是否是唯一的问题,或者错误是否运行得更深,但我们将不胜感激。此外,如果有一种完全更好(并且请更简单)的方法来做到这一点,比如使用 Linq,以及一些很酷的 GroupBy 操作,或者任何其他有趣的方式。

counter

1 个答案:

答案 0 :(得分:1)

<块引用>

喜欢 Linq,还有一些很酷的 GroupBy 操作

我认为您拥有的代码基本上可以替换为:

massings.GroupBy(m => new { m.CPnt.X, Ym.CPnt.Y }).ToDictionary(g => g.Key, g => g.ToList()); 

但它不会导致 Dictionary<int, List<Massing>> - 我无法弄清楚如何在具有 X 和 Y 的点上进行分组在逻辑上会导致单个 int;它应该保持一个 X 和 Y 或者,如果你想要一个整数,并且知道例如Y 永远不会超过 10000,你可以:

massings.GroupBy(m => m.CPnt.X * 10000 + Ym.CPnt.Y).ToDictionary(g => g.Key, g => g.ToList()); 

这将取 X 为 23 和 Y 为 34 并产生 230034(如果您考虑一下,这只是将两个整数编码为一个的基本方法,这样您就可以获得原始 X/ Y 返回一个除法/模运算对)

它的性能可能不如直接自己做,看起来更像是:

var d = new Massing[0].ToDictionary(x => new { m.CPnt.X, Ym.CPnt.Y }, x => new List<Massing>());

foreach(var m in massings){
   var k = new { m.CPnt.X, Ym.CPnt.Y };
   if(!d.ContainsKey(k))
     d[k] = new List<Massing>();
   d[k].Add(m);
}
     

我们需要一点技巧来制作字典;我不相信为了直接声明 Dictionary<AT,List<T>> 可以“获取匿名类型的类型”(因为 AT 是由编译器编写的类型),但我们可以让编译器编写我们需要的位将零长度数组转换为带有一点 LINQ 的空字典,然后在没有 LINQ 的情况下填充它。如果你不想用匿名类型来做这个黑客,你可以看看制作某种元组,或者如果你的 C# 足够现代(或者一个普通的类,如果你想覆盖 equals 和哈希码自己)

相关问题