这个表达式可以简化吗?
Posted
技术标签:
【中文标题】这个表达式可以简化吗?【英文标题】:Can this expression be simplified? 【发布时间】:2021-06-23 07:28:26 【问题描述】:我正在从 Room
对象运行代码,以将特定类型的所有 IRoomDwellers
放入列表中。所有IRoomDwellers
都存储在静态Dictionary<IRoomDweller,Room>
中。
不过,这基本上是我第一次使用Linq
,我觉得(虽然代码似乎可以工作)这个表达式相当笨拙。一方面,我真的不知道GroupBy
增加了什么价值,但没有它似乎无法工作。
方法如下:
private List<T> GetDwellers<T>() where T : IRoomDweller
return RoomDwellers
.GroupBy(z => z.Value)
.SelectMany(z => z)
.Where(z => z.Value == this && z.Key is T)
.Select(z => (T) z.Key)
.ToList();
GroupBy 实际提供什么功能(当我最初的尝试没有奏效时,我从一个示例中抄袭了它)?这个表达式能否以其他方式简化/提高性能?
【问题讨论】:
.SelectMany(z => z)
是多余的 - 它在这里没有任何作用。
我同意GroupBy
似乎毫无意义,因为它与SelectMany
相抵消。当您删除 GroupBy
和 SelectMany
时,什么“不起作用”?
GroupBy
后跟 SelectMany
看起来确实很奇怪。它有效地按Value
对列表进行“排序”。我想您可以将其简化为RoomDwellers.Where(z => z.Value == this).Select(z => z.Key).OfType<T>().ToList();
,但结果的排序方式会有所不同。
@phuzi 我想,但没有它代码将无法工作。如果没有,我无法在 Where 中分离出键/值对。
“无法分离出键/值对”是什么意思?您收到错误消息吗?您是否得到与预期输出不同的东西?如果有,您的预期产出和实际产出是多少?
【参考方案1】:
拥有一本字典(如果您有 RoomDweller,旨在用于获取 Room)并以错误的方式使用它(您拥有 Room 并想要获取 RoomDweller)并不理想,但是:
return RoomDwellers.Where(rdkvp => rdkvp.Value == this && rdkvp.Key is T)
.Select(rdkvp => rdkvp.Key)
.ToList();
RoomDwellers 是 KeyValuePair 的列表,Key 是 RoomDweller,Value 是 Room.. 所以你可以枚举 KVP 的列表,选择 Value 是这个房间的那些,然后返回关联的 Key(RoomDweller)
【讨论】:
这不会让我只获得特定类型的 RoomDweller,对吗?而且,是的,这并不理想,但它似乎是防止双重存储我的值的唯一方法(因为我也需要从 RoomDweller 访问它的房间)。 那么你真的应该有两个字典,一个用于每个映射方向,或者如果(正如数据结构似乎暗示的那样)RoomDweller 可能只有一个 Room,这可能是 Dweller 的属性,而 Room 有一个 Dwellers 列表。 我想避免像这样保持两位数据同步。你肯定明白吗?太容易出错... 然后创建一个包含两个字典的类,其唯一目的是使它们保持同步;一个双向字典本身。我很高兴承认有很多我不明白的东西,人们希望将他们将查找的东西放在价值方面,并将他们想要获得的数据作为字典的关键方面,因为例子。字典在键 -> 值的方向上处理哈希表,并且非常非常快。当您想在 value->key 的方向上查找内容时,它们会很慢,因为它需要一个循环结构来访问每个值 一个房间可以有多个住户。比迪不行。不过,谢谢,您提供了很多值得思考的见解。以上是关于这个表达式可以简化吗?的主要内容,如果未能解决你的问题,请参考以下文章
为什么匿名内部类可以实例化并实现抽象方法?lambda表达式是简化了匿名内部类的实现过程吗?