Lookup <TKey, TElement>의 요점은 무엇입니까? 단일 값에 매핑하는 반면

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

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

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



답변

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이러한 선언의 대부분을 일반 코드로 사용합니다.)


답변

: 그것에 대해 생각하는 한 가지 방법은 이것이 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
        }
    }
}

답변

한 가지 용도는 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마다 후자 변경. 그러나 일부 데이터의 경우 올바른 솔루션이 될 수 있습니다.]


답변

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

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


답변

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

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

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