【问题标题】: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 =&gt; z) 是多余的 - 它在这里没有任何作用。
  • 我同意GroupBy 似乎毫无意义,因为它与SelectMany 相抵消。当您删除 GroupBySelectMany 时,什么“不起作用”?
  • GroupBy 后跟 SelectMany 看起来确实很奇怪。它有效地按Value 对列表进行“排序”。我想您可以将其简化为RoomDwellers.Where(z =&gt; z.Value == this).Select(z =&gt; z.Key).OfType&lt;T&gt;().ToList();,但结果的排序方式会有所不同。
  • @phuzi 我想,但没有它代码将无法工作。如果没有,我无法在 Where 中分离出键/值对。
  • “无法分离出键/值对”是什么意思?您收到错误消息吗?您是否得到与预期输出不同的东西?如果有,您的预期产出和实际产出是多少?

标签: c# linq dictionary


【解决方案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 的方向上查找内容时,它们会很慢,因为它需要一个循环结构来访问每个值
  • 一个房间可以有多个住户。比迪不行。不过,谢谢,您提供了很多值得思考的见解。
猜你喜欢
  • 2017-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多