gpt4 book ai didi

linq - 创建 ILookups

转载 作者:行者123 更新时间:2023-12-05 00:39:16 26 4
gpt4 key购买 nike

我有一个由一些复杂的表达式生成的 ILookup。假设这是按姓氏查找人。 (在我们简单的世界模型中,姓氏在家庭中是唯一的)

ILookup<string, Person> families;

现在我有两个对如何构建感兴趣的查询。

首先,我将如何按姓氏过滤?
var germanFamilies = families.Where(family => IsNameGerman(family.Key));

但是在这里, germanFamiliesIEnumerable<IGrouping<string, Person>> ;如果我调用 ToLookup()在它上面,我最好打赌会得到一个 IGrouping<string, IGrouping<string, Person>> .如果我尝试变得聪明并调用 SelectMany首先,我最终会让计算机做很多不必要的工作。您将如何轻松将此枚举转换为查找?

其次,我只想查找成年人。
var adults = families.Select(family =>
new Grouping(family.Key, family.Select(person =>
person.IsAdult())));

这里我面临两个问题: Grouping type 不存在(除了 Lookup 的内部内部类),即使存在,我们也会遇到上面讨论的问题。

所以,除了完全实现 ILookup 和 IGrouping 接口(interface),或者让计算机做大量的工作(重新组合已经分组的内容)之外,有没有办法改变现有的 ILookup 以生成我错过的新 ILookup?

最佳答案

(根据您的查询,我假设您实际上想按姓氏过滤。)

您不能修改 ILookup<T> 的任何实现我知道。 implement ToLookup with an immutable lookup当然可以,正如你清楚地知道的:)

但是,您可以做的是更改为使用 Dictionary<string, List<Person>> :

var germanFamilies = families.Where(family => IsNameGerman(family.Key))
.ToDictionary(family => family.Key,
family.ToList());

该方法也适用于您的第二个查询:
var adults = families.ToDictionary(family => family.Key,
family.Where(person => persion.IsAdult)
.ToList());

虽然这仍然比我们认为必要的要多,但还不错。

编辑:评论中与 Ani 的讨论值得一读。基本上,无论如何我们已经要迭代每个人了——所以如果我们假设 O(1) 字典查找和插入,我们实际上在使用现有查找的时间复杂度方面并没有比展平更好:
var adults = families.SelectMany(x => x)
.Where(person => person.IsAdult)
.ToLookup(x => x.LastName);

在第一种情况下,我们可能会使用现有的分组,如下所示:
// We'll have an IDictionary<string, IGrouping<string, Person>>
var germanFamilies = families.Where(family => IsNameGerman(family.Key))
.ToDictionary(family => family.Key);

那么这可能会更有效率(如果我们每个家庭中有很多人),但这意味着我们正在“脱离上下文”使用分组。我相信这实际上没问题,但出于某种原因,它在我的嘴里留下了一点奇怪的味道。如 ToLookup实现查询,但很难看出它实际上是如何出错的......

关于linq - 创建 ILookups,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4650777/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com