Lookup <TKey, TElement>의 요점은 무엇입니까?


155

MSDN은 Lookup을 다음과 같이 설명합니다.

A는 Lookup<TKey, TElement> 유사합니다 Dictionary<TKey, TValue>. 차이점은 Dictionary <TKey, TValue> 는 키를 단일 값에 매핑하는 반면 Lookup <TKey, TElement> 는 키를 값 컬렉션에 매핑한다는 것입니다.

그 설명이 특히 도움이되지 않습니다. 조회는 무엇을 위해 사용됩니까?

답변:


215

IGrouping사전과 사전 사이의 교차점 입니다. 키를 사용하여 항목을 그룹화 한 다음 모든 항목을 반복하는 것이 아니라 효율적인 방식으로 해당 키를 통해 항목에 액세스 할 GroupBy수 있습니다.

예를 들어, 많은 .NET 유형을 가져와 네임 스페이스별로 조회를 구축 한 다음 특정 네임 스페이스의 모든 유형을 매우 쉽게 얻을 수 있습니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;

public class Test
{
    static void Main()
    {
        // Just types covering some different assemblies
        Type[] sampleTypes = new[] { typeof(List<>), typeof(string), 
                                     typeof(Enumerable), typeof(XmlReader) };

        // All the types in those assemblies
        IEnumerable<Type> allTypes = sampleTypes.Select(t => t.Assembly)
                                               .SelectMany(a => a.GetTypes());

        // Grouped by namespace, but indexable
        ILookup<string, Type> lookup = allTypes.ToLookup(t => t.Namespace);

        foreach (Type type in lookup["System"])
        {
            Console.WriteLine("{0}: {1}", 
                              type.FullName, type.Assembly.GetName().Name);
        }
    }
}

(일반적으로 var이러한 선언의 대부분을 일반 코드로 사용합니다.)


59
나는이 대답을 더 잘하기 위해 일부 변수를 대체 할 수 있다고 생각합니다. 학습 목적을 위해 유형이 명확하게 표현 될 때 따라 가기가 더 쉽다고 생각합니다. 그냥 내 2 센트 :)
Alex Baranosky

3
그것이 두 세계의 최고를 가지고 있다면 왜 사전을 귀찮게합니까?
Kyle Baran

15
@KyleBaran : 키당 하나의 값만있는 진정한 키 / 값 쌍 컬렉션에는 의미가 없기 때문입니다.
Jon Skeet

12
@KyleBaran Lookup<,>Add사용이 제한된 불변의 컬렉션입니다 ( 예 : 방법 이 없음 ). 또한 존재하지 않는 키를 조회하면 예외가 아닌 빈 시퀀스를 얻습니다. 예를 들어 linq와 같은 특수한 컨텍스트에서만 의미가 있습니다. 이것은 MS가 클래스에 대한 공개 생성자를 제공하지 않았다는 사실과 잘 어울립니다.
nawfal

답변 순서 읽기 jwg-> bobbymcr-> jonskeet
snr

58

: 그것에 대해 생각하는 한 가지 방법은 이것이 Lookup<TKey, TElement>유사하다 Dictionary<TKey, Collection<TElement>>. 기본적으로 동일한 키를 통해 0 개 이상의 요소 목록이 반환 될 수 있습니다.

namespace LookupSample
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    class Program
    {
        static void Main(string[] args)
        {
            List<string> names = new List<string>();
            names.Add("Smith");
            names.Add("Stevenson");
            names.Add("Jones");

            ILookup<char, string> namesByInitial = names.ToLookup((n) => n[0]);

            // count the names
            Console.WriteLine("J's: {0}", namesByInitial['J'].Count()); // 1
            Console.WriteLine("S's: {0}", namesByInitial['S'].Count()); // 2
            Console.WriteLine("Z's: {0}", namesByInitial['Z'].Count()); // 0, does not throw
        }
    }
}

2
조회 결과에 요소가 없을 수 있습니까? 어떻게 알 겠어요? (Lookup은 내가 말할 수있는 한 공개적으로 불변이며 ToLookup이 효과적으로 키를 발명 할 것이라고는 생각하지 않습니다.)
Jon Skeet

8
기술적으로, 예, Lookup은 존재하지 않는 키에 대한 빈 컬렉션을 반환하기 때문에 (이를 보여주는 코드 샘플을 추가하기 위해 게시물을 편집했습니다).
bobbymcr

답변 순서 읽기 jwg-> bobbymcr-> jonskeet
snr

매우 깨끗하고 유용한 답변입니다.

25

한 가지 용도는 Lookup을 뒤집을 수 있습니다 Dictionary.

전화 번호부에 Dictionary연결된 고유 한 이름을 키로 사용 하여 전화 번호부를 구현했다고 가정합니다 . 그러나 이름이 다른 두 사람이 같은 전화 번호를 공유 할 수 있습니다. 이것은 Dictionary두 개의 키가 동일한 값에 해당하는 것을 신경 쓰지 않는에 대한 문제 가 아닙니다.

이제 당신은 주어진 전화 번호가 누구인지 찾는 방법을 원합니다. 당신은을 구축 Lookup하는 모든 추가, KeyValuePairs당신의 Dictionary키와 값으로 키와 값으로,하지만 거꾸로입니다. 이제 전화 번호를 쿼리하고 전화 번호를 가진 모든 사람의 이름 목록을 얻을 수 있습니다. Dictionary동일한 데이터로 a 를 작성하면 데이터가 삭제되거나 수행 방식에 따라 실패합니다.

dictionary["555-6593"] = "Dr. Emmett Brown";
dictionary["555-6593"] = "Marty McFly";

즉, 두 번째 항목이 첫 번째 항목을 덮어 씁니다. 문서가 더 이상 나열되지 않습니다.

동일한 데이터를 약간 다른 방식으로 쓰려고합니다.

dictionary.Add("555-6593", "Dr. Emmett Brown");
dictionary.Add("555-6593", "Marty McFly");

Add이미에있는 키를 사용할 수 없으므로 두 번째 줄에 예외가 발생 합니다 Dictionary.

[물론, 당신은 당신이 다시 생성해야 함을 의미 등 양방향으로 조회를 수행하는 다른 하나의 데이터 구조를 사용하는 예제를 할 수 있습니다 Lookup로부터 Dictionary마다 후자 변경. 그러나 일부 데이터의 경우 올바른 솔루션이 될 수 있습니다.]


답은 개념을 이해하는 데 필수적입니다. +1. 답변 순서 읽기 jwg-> bobbymcr-> jonskeet
snr

15

나는 그것을 성공적으로 사용하지 않았지만 여기에 내 이동이 있습니다 :

A Lookup<TKey, TElement>는 고유 제한 조건이없는 테이블의 (관계형) 데이터베이스 인덱스와 매우 유사하게 작동합니다. 다른 곳과 같은 곳에서 사용하십시오.


5

전화 번호부의 내용을 담을 데이터 구조를 만들고 있다고 상상해보십시오. lastName을 입력 한 다음 firstName을 입력하려고합니다. 많은 사람들이 같은 이름을 가질 수 있기 때문에 여기서 사전을 사용하는 것은 위험합니다. 따라서 사전은 항상 단일 값으로 매핑됩니다.

조회는 잠재적으로 여러 값에 매핑됩니다.

조회 [ "Smith"] [ "John"]는 10 억 크기의 모음입니다.


귀하의 답변에 대한 후속 질문 인 "여러 인덱스가있는 ToLookup () 방법"에 영감을주었습니다. . 여러 색인으로 조회를 어떻게 재현 할 수 있습니까? 사용 가능한 다른 샘플이나 참조를 사용하여 대답 할 수 Lookup["Smith"]["John"] 있습니까?
Fulproof
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.