C#

[C#]Dictionary 특정 값이 존재하는지 확인하는 방법

DevStory 2022. 8. 19.

Dictionary 특정 값이 존재하는지 확인하는 방법

C#의 Dictionary 클래스는 <Key, Value> 형식의 데이터를 가지는 컬렉션으로 키(Key)는 중복되지 않은 고유한 값을 할당하지만, 값(Value)은 중복되는 값이 할당될 수 있습니다.

 

다음 예제처럼 키는 중복되지 않지만, 값이 중복되는 데이터를 Dictionary에 추가할 수 있습니다.

class Program
{
  static void Main(string[] args)
  {
    Dictionary<String, int> dict = new Dictionary<String, int>();
    dict.Add("A", 1000);
    dict.Add("B", 1000);
    dict.Add("C", 1000);

    foreach(KeyValuePair<String ,int> item in dict)
    {
      Console.WriteLine("Key: " + item.Key + ", Value: " + item.Value);
    }
  }
}

[실행 결과]

Key: A, Value: 1000
Key: B, Value: 1000
Key: C, Value: 1000

하지만, 다음 예제처럼 중복되는 데이터를 키에 추가하는 경우 런타임 에러가 발생합니다.

class Program
{
  static void Main(string[] args)
  {
    Dictionary<String, int> dict = new Dictionary<String, int>();
    dict.Add("A", 1000);
    dict.Add("A", 2000);
  }
}

[에러 내용]

이번 포스팅은 Dictionary에 값이 존재하는지 확인할 수 있는 몇 가지 방법을 소개합니다.


방법 1. 반복문

가장 심플한 방법으로 반복문을 사용하여 Dictionary에 특정 값이 존재하는지 확인할 수 있습니다.

 

다음 예제는 Dictionary에 특정 값이 존재하는지 확인하는 isHasValue() 메서드를 정의하였으며, 특정 값이 존재하면 true를 반환하고 그렇지 않으면 false를 반환합니다.

class Program
{
  public static bool isHasValue<K, V>(Dictionary<K, V> dict, V val)
  {
    foreach (KeyValuePair<K, V> kvp in dict)
    {
      if (kvp.Value.Equals(val))
      {
          return true;
       }
    }
    return false;
  }
  
  static void Main(string[] args)
  {
    Dictionary<String, int> dict = new Dictionary<String, int>();
    dict.Add("A", 1000);
    dict.Add("B", 2000);
    dict.Add("C", 3000);

    Console.WriteLine("2000은 Value에 할당되어 있는가? " + isHasValue(dict, 2000));
    Console.WriteLine("4000은 Value에 할당되어 있는가? " + isHasValue(dict, 4000));
  }
}

[실행 결과]

2000은 Value에 할당되어 있는가? True
4000은 Value에 할당되어 있는가? False

방법 2. Dictionary 클래스의 ConatinsValue 메서드

두 번째 방법으로 네임스페이스 System.Collections.Generic에 정의되어 있는 ContainsValue() 메서드를 사용합니다.

 

Dictionary 객체에서 ContainsValue() 메서드를 호출할 수 있으며, 매개변수로 특정 값을 전달합니다.

 

특정 값이 Dictionary에 존재하면 true를 반환하고 그렇지 않으면 false를 반환합니다.

class Program
{
  static void Main(string[] args)
  {
    Dictionary<String, int> dict = new Dictionary<String, int>();
    dict.Add("A", 1000);
    dict.Add("B", 2000);
    dict.Add("C", 3000);

    Console.WriteLine("2000은 Value에 할당되어 있는가? " + 
        dict.ContainsValue(2000));

    Console.WriteLine("4000은 Value에 할당되어 있는가? " + 
        dict.ContainsValue(4000));
  }
}

[실행 결과]

2000은 Value에 할당되어 있는가? True
4000은 Value에 할당되어 있는가? False

방법 3. LINQ의 Any 메서드

세 번째 방법으로 LINQ에서 제공하는 Any() 메서드를 사용합니다.

 

LINQ에서 제공하는 기능을 사용하기 위해 다음 네임스페이스를 소스 코드에 추가합니다.

using System.Linq;

Any() 메서드는 배열 또는 컬렉션과 같은 데이터 집합에서 특정 조건을 만족하는 데이터가 하나라도 있으면, true를 반환하고 그렇지 않으면 false를 반환합니다.

 

다음 예제는 Dicitionary에 특정 값이 존재하는지 확인하는 isHasValue() 메서드를 정의하였으며, Any() 메서드를 사용하여 특정 값이 존재하는지 검사합니다.

 

class Program
{
  public static bool isHasValue<K, V>(Dictionary<K, V> dict, V val)
  {
    return dict.Any(item => item.Value.Equals(val));
  }

  static void Main(string[] args)
  {
    Dictionary<String, int> dict = new Dictionary<String, int>();
    dict.Add("A", 1000);
    dict.Add("B", 2000);
    dict.Add("C", 3000);

    Console.WriteLine("2000은 Value에 할당되어 있는가? " +
        isHasValue(dict, 2000));

    Console.WriteLine("4000은 Value에 할당되어 있는가? " +
        isHasValue(dict, 4000));
  }
}

[실행 결과]

2000은 Value에 할당되어 있는가? True
4000은 Value에 할당되어 있는가? False

LINQ에서 제공하는 Any() 메서드를 사용하는 방법은 아래 포스팅에서 확인할 수 있습니다.

 

[C#]LINQ 특정 조건을 만족하는지 체크하는 방법 - All, Any 메서드

Quantifiers 연산 Quantifiers 연산은 컬렉션과 같은 데이터 집합에서 모든 요소들이 특정 조건을 만족하는지 확인할 수 있는 방법들을 제공합니다. Quantifiers 연산에서 제공하는 메서드인 All(), Any(), Con

developer-talk.tistory.com


방법 4. 값이 사용자가 정의한 클래스 타입인 경우

Dictionary 객체의 값이 기본 타입이 아닌 사용자가 정의한 클래스 타입인 경우 특정 값이 존재하는지 검사하는 방법이 생각보다 까다로워집니다.

 

다음 예제는 Dictionary의 값이 사용자가 정의한 클래스인 Person 타입입니다.

 

Dictionary의 값이 기본 타입이 아닌 경우 객체의 참조 값을 비교하므로 다음 예제처럼 동일한 프로퍼티 값을 가지는 객체를 값으로 등록해도 Any() 메서드와 ContainsValue() 메서드는 false를 반환합니다.

public class Person
{
  public string Name { get; set; }
  public int Age { get; set; }
}

class Program
{
  public static bool isHasValue<K, V>(Dictionary<K, V> dict, V val)
  {
    return dict.Any(item => item.Value.Equals(val));
  }

  static void Main(string[] args)
  {
    Dictionary<String, Person> dict = new Dictionary<String, Person>();
    dict.Add("A", new Person() { Name = "둘리", Age = 10 });
    dict.Add("B", new Person() { Name = "둘리", Age = 10 });

    Console.WriteLine("new Person() { Name = \"둘리\", Age = 10 }은 Value에 할당되어 있는가? " +
        isHasValue(dict, new Person() { Name = "둘리", Age = 10 }));

    Console.WriteLine("new Person() { Name = \"둘리\", Age = 10 }은 Value에 할당되어 있는가? " +
        dict.ContainsValue(new Person() { Name = "둘리", Age = 10 }));
  }
}

[실행 결과]

new Person() { Name = "둘리", Age = 10 }은 Value에 할당되어 있는가? False
new Person() { Name = "둘리", Age = 10 }은 Value에 할당되어 있는가? False

객체의 참조 값이 아닌 프로퍼티 값을 비교하도록 Person 클래스에서 Equals() 메서드와 GetHashCode() 메서드를 재정의합니다.

 

다음 예제는 Equals() 메서드와 GetHashCode() 메서드를 재정의 후 Person 타입의 객체가 Dictionary의 특정 값으로 존재하는지 검사합니다.

public class Person
{
  public string Name { get; set; }
  public int Age { get; set; }

  public override bool Equals(object x)
  {
    return this.Name == ((Person)x).Name && this.Age == ((Person)x).Age;
  }

  public override int GetHashCode()
  {
    return this.Name.GetHashCode() ^ this.Age.GetHashCode();
  }
}

class Program
{
  public static bool isHasValue<K, V>(Dictionary<K, V> dict, V val)
  {
    return dict.Any(item => item.Value.Equals(val));
  }

  static void Main(string[] args)
  {
    Dictionary<String, Person> dict = new Dictionary<String, Person>();
    dict.Add("A", new Person() { Name = "둘리", Age = 10 });
    dict.Add("B", new Person() { Name = "둘리", Age = 10 });

    Console.WriteLine("new Person() { Name = \"둘리\", Age = 10 }은 Value에 할당되어 있는가? " +
        isHasValue(dict, new Person() { Name = "둘리", Age = 10 }));

    Console.WriteLine("new Person() { Name = \"둘리\", Age = 10 }은 Value에 할당되어 있는가? " +
        dict.ContainsValue(new Person() { Name = "둘리", Age = 10 }));
  }
}

[실행 결과]

new Person() { Name = "둘리", Age = 10 }은 Value에 할당되어 있는가? True
new Person() { Name = "둘리", Age = 10 }은 Value에 할당되어 있는가? True
반응형

댓글