我一直有麻烦关节之间的差异ILookup<TKey, TVal>
和IGrouping<TKey, TVal>
,并很好奇,如果我理解正确了.LINQ通过生成IGrouping
项目序列来复杂化问题,同时也为我提供了ToLookup
扩展方法.所以在我仔细观察之前感觉它们是一样的.
var q1 =
from n in N
group n by n.MyKey into g
select g;
// q1 is IEnumerable<IGrouping<TKey, TVal>>
Run Code Online (Sandbox Code Playgroud)
这相当于:
var q2 = N.GroupBy(n => n.MyKey, n => n);
// q2 is IEnumerable<IGrouping<TKey, TVal>>
Run Code Online (Sandbox Code Playgroud)
这看起来很像:
var q3 = N.ToLookup(n => n.MyKey, n => n);
// q3 is ILookup<TKey, TVal>
Run Code Online (Sandbox Code Playgroud)
我在以下类比中是否正确?
IGrouping<TKey, TVal>
是一个单独的组(即键控序列),类似于KeyValuePair<TKey, TVal>
值实际上是一系列元素(而不是单个元素)IEnumerable<IGrouping<TKey, TVal>>
是那些序列(类似于迭代时得到的结果)IDictionary<TKey, TVal>
ILookup<TKey, TVal>
更像是一个IDictionary<TKey, …
我有一个返回的方法ILookup
.在某些情况下,我想ILookup
提前退出一个空.构建空的最佳方法是ILookup
什么?
假设我有一个(有序的)动物序列:
Eagle Elephant Tarantula Terrapin Tiger
我按第一封信分组:
Animals.GroupBy(animal => animal.First())
Run Code Online (Sandbox Code Playgroud)
IGrouping
结果序列中s 的元素是否与输入序列的顺序相同?
是否有一个快速的方式来获得扁平List<TElement>
从ILookup<TKey, TElement>
一个从创建的IEnumerable<TElement>
扩展?
更新了示例
List<int> list = new List<int>();
var lookup = list.ToLookup(key => key);
list = lookup.?? // How to convert the lookup back to the list
Run Code Online (Sandbox Code Playgroud) 我有两个类型ILookup的变量.我想使用Union或Concat组合它们的值并将结果分配给相同类型的第三个变量.Union和Concat都返回IGrouping.将IGrouping转换为ILookup一定很简单,但我不能这样做!:-( IGrouping暴露了Key,所以我正在努力寻找Lookup的第二个参数....任何帮助都会非常多,非常感谢.
我有一个由一些复杂表达式生成的 ILookup。假设这是按姓氏查找人。(在我们简单化的世界模型中,姓氏在家庭中是唯一的)
ILookup<string, Person> families;
Run Code Online (Sandbox Code Playgroud)
现在我有两个疑问,我对如何构建感兴趣。
首先,我如何按姓氏过滤?
var germanFamilies = families.Where(family => IsNameGerman(family.Key));
Run Code Online (Sandbox Code Playgroud)
但这里germanFamilies
有一个IEnumerable<IGrouping<string, Person>>
; 如果我调用ToLookup()
它,我最好打赌会得到一个IGrouping<string, IGrouping<string, Person>>
. 如果我想聪明点,SelectMany
先打电话,我最终会发现计算机做了很多不必要的工作。如何轻松地将这个枚举转换为查找?
其次,我只想查询成年人的信息。
var adults = families.Select(family =>
new Grouping(family.Key, family.Select(person =>
person.IsAdult())));
Run Code Online (Sandbox Code Playgroud)
在这里,我面临两个问题:Grouping
类型不存在(除了作为 的内部内部类Lookup
),即使存在,我们也会遇到上面讨论的问题。
那么,除了完全实现 ILookup 和 IGrouping 接口,或者让计算机做大量愚蠢的工作(重新分组已经分组的内容)之外,是否有办法改变现有的 ILookups 以生成我错过的新 ILookups?
我想使用 Linq 创建一个函数来总结传入的值序列。该函数应该如下所示:
IDictionary<TKey, Summary<TKey>> Summarize<TKey, TValue>(IEnumerable<TValue> values)
{
return values
.ToLookup(val => GetKey(val)) // group values by key
.Union(*an empty grouping*) // make sure there is a default group
.ToDictionary(
group => group.Key,
group => CreateSummary(group)); // summarize each group
}
Run Code Online (Sandbox Code Playgroud)
问题是,即使传入序列不包含具有该键的值,生成的 IDictionary 也应该有一个 default(TKey) 条目。这可以以纯函数的方式完成吗?(不使用可变数据结构。)
我能想到的唯一方法是在将其输入字典之前调用 .Union 进行查找。但这需要我创建一个空的 IGrouping,如果没有显式类,这似乎是不可能的。有没有一种优雅的方法来做到这一点?
编辑:我们可以假设 TKey 是一种值类型。
我想根据其值过滤linq Lookup:
查找:
ILookup<int, Article> lookup
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止所做的不起作用:
IList<int> cityIndexes = GetCityIndexesByNames(cities);
lookup = lookup
.Where(p => p.Any(x => cityIndexes.Contains((int)x.ArticleCity)))
.SelectMany(l => l)
.ToLookup(l => (int)l.ArticleParentIndex, l => l);
Run Code Online (Sandbox Code Playgroud)
只是为了澄清:我想获得所有带有上述城市索引列表中包含的城市索引的文章.