ILookup 대 IGrouping
나는 사이의 차이를 분명히 말하는 데 문제가 있었어요 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>>
다음과 같습니다.
var q2 = N.GroupBy(n => n.MyKey, n => n);
// q2 is IEnumerable<IGrouping<TKey, TVal>>
다음과 같이 보입니다.
var q3 = N.ToLookup(n => n.MyKey, n => n);
// q3 is ILookup<TKey, TVal>
나는 다음 비유에서 맞습니까?
- An
IGrouping<TKey, TVal>
은KeyValuePair<TKey, TVal>
값이 실제로 요소의 시퀀스 (단일 요소가 아닌 ) 인 경우와 유사한 단일 그룹 (예 : 키순 )입니다. - An
IEnumerable<IGrouping<TKey, TVal>>
은 그것들의 시퀀스입니다 (반복 할 때 얻는 것과 유사합니다.IDictionary<TKey, TVal>
- An
ILookup<TKey, TVal>
은IDictionary<TKey, TVal>
값이 실제로 요소의 시퀀스 인 것과 비슷합니다 .
예, 모두 정확합니다.
그리고 ILookup<TKey, TValue>
또한 확장 IEnumerable<IGrouping<TKey, TValue>>
모든 키 / 수집 쌍을 반복뿐만 아니라 (또는 대신에) 단지 특정 키를 찾는 수 있습니다.
기본적으로 내가 생각 ILookup<TKey,TValue>
처럼 것으로 IDictionary<TKey, IEnumerable<TValue>>
.
마음에 베어 ToLookup
A는 반면 "지금 당장"작업 (즉시 실행)입니다 GroupBy
지연됩니다. "pull LINQ"가 작동하는 방식 IGrouping
으로 a 결과에서 s를 가져 오기 시작 GroupBy
하면 (중간에 그룹을 전환 할 수 없기 때문에) 어쨌든 모든 데이터를 읽어야하는 반면 다른 구현에서는 스트리밍 결과를 생성 할 수 있습니다. (Push LINQ에서 수행됩니다. LINQ to Events가 동일 할 것으로 예상합니다.)
ILookup과 IDictionary 사이에는 또 다른 중요한 차이점이 있습니다. 전자는 여기에 데이터를 변경하는 방법이 없다는 점에서 불변성을 적용합니다 (소비자가 명시 적 캐스트를 수행하는 경우 제외). 반대로 IDictionary에는 데이터를 변경할 수있는 "Add"와 같은 메서드가 있습니다. 따라서 기능 프로그래밍 및 / 또는 병렬 프로그래밍의 관점에서 보면 ILookup이 더 좋습니다. (그룹이 아닌 키에 하나의 값만 할당하는 ILookup 버전도 있었으면합니다.)
(Btw., IEnumerable과 IList 사이의 관계는 ILookup과 IDictionary 사이의 관계와 다소 유사하다는 점을 지적 할 가치가있는 것 같습니다. 전자는 불변이고 후자는 그렇지 않습니다.)
GroupBy
다음을 제외ToLookUp
하고 거의 동일한 기능 이 있습니다. 참조
GroupBy : GroupBy 연산자는 일부 키 값을 기반으로 요소 그룹을 반환합니다. 각 그룹은 IGrouping 개체로 표시됩니다.
ToLookup : ToLookup은 GroupBy와 동일합니다. 유일한 차이점은 GroupBy 실행이 지연되는 반면 ToLookup 실행은 즉시 수행된다는 것입니다.
샘플 코드를 사용하여 차이점을 정리해 보겠습니다. Person
모델을 나타내는 클래스가 있다고 가정합니다 .
class Personnel
{
public int Id { get; set; }
public string FullName { get; set; }
public int Level { get; set; }
}
그 후 personnels
아래와 같이 목록을 정의 합니다.
var personnels = new List<Personnel>
{
new Personnel { Id = 1, FullName = "P1", Level = 1 },
new Personnel { Id = 2, FullName = "P2", Level = 2 },
new Personnel { Id = 3, FullName = "P3", Level = 1 },
new Personnel { Id = 4, FullName = "P4", Level = 1 },
new Personnel { Id = 5, FullName = "P5", Level =2 },
new Personnel { Id = 6, FullName = "P6", Level = 2 },
new Personnel { Id = 7, FullName = "P7", Level = 2 }
};
이제 personnels
레벨별로 그룹화해야합니다. 여기에 두 가지 접근 방식이 있습니다. 사용 GroupBy
또는 ToLookUp
. 내가 사용하는 경우 GroupBy
, 이전에 언급 한 바와 같이, 그것은 연기 실행이 수단을 사용이 요구 될 때까지 반복 처리가 컬렉션을 통해 다음 항목이나 계산되지 않을 수 있습니다 때.
var groups = personnels.GroupBy(p => p.Level);
personnels.RemoveAll(p => p.Level == 1);
foreach (var product in groups)
{
Console.WriteLine(product.Key);
foreach (var item in product)
Console.WriteLine(item.Id + " >>> " + item.FullName + " >>> " + item.Level);
}
In the above code, I firstly grouped the personnels
, but before iterating it, I removed some personnels
. As GroupBy
uses deferred execution, so the final result will not include the removed items, because grouping will be computing in the foreach
point here.
Output:
2
2 >>> P2 >>> 2
5 >>> P5 >>> 2
6 >>> P6 >>> 2
7 >>> P7 >>> 2
But if I rewrite the above code as below:(note that code is same as the previous code except GroupBy
is replaced by ToLookUp
)
var groups = personnels.ToLookup(p => p.Level);
personnels.RemoveAll(p => p.Level == 1);
foreach (var product in groups)
{
Console.WriteLine(product.Key);
foreach (var item in product)
Console.WriteLine(item.Id + " >>> " + item.FullName + " >>> " + item.Level);
}
As ToLookUp
uses immediate execution, it means that when I call the ToLookUp
method, result is generated and group is applied, so if I remove any item from personnels
prior to iteration, that wont effect the final result.
Output:
1
1 >>> P1 >>> 1
3 >>> P3 >>> 1
4 >>> P4 >>> 1
2
2 >>> P2 >>> 2
5 >>> P5 >>> 2
6 >>> P6 >>> 2
7 >>> P7 >>> 2
Note: GroupBy
and ToLookUp
both return different types too.
You might use ToDictionary instead of ToLookUp, but you need to pay attention to this:(reference)
The usage of ToLookup() is very similar to that of ToDictionary(), both allow you to specify key selectors, value selectors, and comparers. The main difference is that ToLookup() allows (and expects) the duplicate keys whereas ToDictionary() does not
참고URL : https://stackoverflow.com/questions/1337539/ilookuptkey-tval-vs-igroupingtkey-tval
'Programing' 카테고리의 다른 글
최종 일관성에 사용할 머클 트리 설명 (0) | 2020.10.25 |
---|---|
Android가 물리적 USB 키보드로 작동하도록 프로그래밍 할 수 있습니까? (0) | 2020.10.25 |
Javadoc 재사용 및 오버로드 된 메소드 (0) | 2020.10.25 |
복잡한 다각형을 어떻게 결합합니까? (0) | 2020.10.25 |
.NET System.InvalidOperationException에 해당하는 Java (0) | 2020.10.25 |