C#에서 하나 이상의 속성을 기반으로 고유한 목록 얻기

Bilal Shahid 2023년10월12일
  1. GroupBy()Select()를 사용하여 C#의 한 속성을 기반으로 고유한 목록 얻기
  2. GroupBy()Select()를 사용하여 C#의 하나 이상의 속성을 기반으로 고유한 목록 얻기
  3. DistinctBy를 사용하여 C#의 하나 이상의 속성을 기반으로 고유한 목록 얻기
C#에서 하나 이상의 속성을 기반으로 고유한 목록 얻기

오늘 우리는 다른 값을 포함하는 동일한 속성을 가진 여러 개체에 대해 LINQ에서 Distinct()를 사용하는 방법을 살펴보겠습니다. 먼저 아래 예를 살펴보십시오.

CAR one, CAR twoCAR three의 세 개체가 있다고 가정합니다. CAR oneCAR two에는 빌드 값 2가 포함되지만 CAR three에는 빌드 값 4가 포함됩니다.

세 개체에서 Distinct()를 호출할 때 결과에는 CAR oneCAR three 또는 CAR twoCAR three만 포함되어야 합니다. 둘 다 고유한 값을 포함하기 때문입니다.

이 문서에서는 C#에서 하나 이상의 속성을 기반으로 고유한 목록을 얻는 방법에 대해 설명합니다.

GroupBy()Select()를 사용하여 C#의 한 속성을 기반으로 고유한 목록 얻기

따라서 예제를 시작하기 전에 먼저 코드에 LINQ 라이브러리를 추가해 보겠습니다.

using SYSTEM.Linq;

그런 다음 다음과 같이 CAR 클래스를 정의해 보겠습니다.

class CAR {
  public int id;

  public CAR(int id) {
    this.id = id;
  }
}

그런 다음 Main에서 몇 가지 개체를 정의해 보겠습니다.

CAR one = new CAR(4);
CAR two = new CAR(4);
CAR three = new CAR(6);

List<CAR> cars = new List<CAR>();
cars.Add(one);
cars.Add(two);
cars.Add(three);

또한 목록을 만들고 여기에 세 개의 개체를 추가했습니다. 동일한 속성 개체를 트리밍하고 그중 하나만 고려합니다.

새 목록을 만든 다음 GroupBY() 절을 사용합니다. 그리고 마지막으로 우승자를 뽑는 First().

List<CAR> distinct_c = cars.GroupBy(p => p.id).Select(g => g.First()).ToList();
for (int i = 0; i < distinct_c.Count(); i++) {
  Console.Write(distinct_c[i].id + " ");
}

결과는 다음과 같이 나옵니다.

4 6

이들은 세 개체 각각에 있는 두 개의 고유한 ID였습니다. 전체 코드는 다음과 같습니다.

class pointer {
  class CAR {
    public int id;

    public CAR(int id) {
      this.id = id;
    }
  }

  public static void Main(String[] args) {
    CAR one = new CAR(4);
    CAR two = new CAR(4);
    CAR three = new CAR(6);

    List<CAR> cars = new List<CAR>();
    cars.Add(one);
    cars.Add(two);
    cars.Add(three);

    List<CAR> distinct_c = cars.GroupBy(p => p.id).Select(g => g.First()).ToList();
    for (int i = 0; i < distinct_c.Count(); i++) {
      Console.Write(distinct_c[i].id + " ");
    }
  }
}

위의 코드를 네임스페이스에 삽입한 다음 사용하십시오.

GroupBy()Select()를 사용하여 C#의 하나 이상의 속성을 기반으로 고유한 목록 얻기

id와 함께 color라는 속성이 하나 더 있고 여전히 고유한 속성을 선택하고 싶다면 어떻게 해야 할까요? 다음과 같이 CAR 클래스에 color 속성을 추가해 보겠습니다.

class CAR {
  public int id;
  public string color;

  public CAR(int id, string color) {
    this.id = id;
    this.color = color;
  }
}

그러나 이제 위와 동일한 구문을 사용하여 함수를 호출해야 합니다.

CAR one = new CAR(4, "red");
CAR two = new CAR(4, "blue");
CAR three = new CAR(6, "blue");

List<CAR> cars = new List<CAR>();
cars.Add(one);
cars.Add(two);
cars.Add(three);

List<CAR> distinct_c = cars.GroupBy(p => p.id).Select(g => g.First()).ToList();
for (int i = 0; i < distinct_c.Count(); i++) {
  Console.Write(distinct_c[i].id + " ");
}

출력은 4 6과 동일하게 유지됩니다. p는 여전히 p => p.id에 의해서만 그룹화되기 때문입니다. 그러나 이제 색상으로도 구분하기를 원하므로 다음과 같이 할 수 있습니다.

List<CAR> distinct_c = cars.GroupBy(p => (p.id, p.color)).Select(g => g.First()).ToList();
for (int i = 0; i < distinct_c.Count(); i++) {
  Console.Write(distinct_c[i].id + " ");
}

결과는 어떻게 될까요? 세 개체는 IDCAR의 조합이 모두 다르기 때문입니다. (4, 빨간색), (4, 파란색)(6, 파란색). 그러므로 모든 대상 사이에는 구별이 있다.

이제 출력은 다음과 같습니다.

4 4 6

전체 코드는 다음과 같습니다.

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

static class pointer {
  class CAR {
    public int id;
    public string color;

    public CAR(int id, string color) {
      this.id = id;
      this.color = color;
    }
  }

  public static void Main(String[] args) {
    CAR one = new CAR(4, "red");
    CAR two = new CAR(4, "blue");
    CAR three = new CAR(6, "blue");

    List<CAR> cars = new List<CAR>();
    cars.Add(one);
    cars.Add(two);
    cars.Add(three);

    List<CAR> distinct_c = cars.GroupBy(p => (p.id, p.color)).Select(g => g.First()).ToList();
    for (int i = 0; i < distinct_c.Count(); i++) {
      Console.Write(distinct_c[i].id + " ");
    }
  }
}

Where 조건을 추가하여 p.id가 null이 아닌지 확인한 다음 호출할 수도 있습니다.

List<CAR> distinct_c =
    cars.Where(p => p.id != null).GroupBy(p => (p.id, p.color)).Select(g => g.First()).ToList();
for (int i = 0; i < distinct_c.Count(); i++) {
  Console.Write(distinct_c[i].id + " ");
}

결과도 마찬가지일 것입니다.

C#에서 First()를 사용할 때 고려할 사항

경우에 따라 FirstorDefault()를 사용할 수 있습니다. First()와 동일한 기능을 수행하지만 첫 번째 요소가 없으면 기본값을 반환하는 또 다른 함수입니다.

null 값에서 오류를 해결하는 데 사용할 수 있습니다.

DistinctBy를 사용하여 C#의 하나 이상의 속성을 기반으로 고유한 목록 얻기

C#에서 고유한 값을 반환할 수 있는 함수를 작성할 수 있습니다.

한 가지 방법은 키와 값을 가져와 함께 매핑할 수 있는 해시 테이블을 사용하는 것입니다. 다음과 같은 함수를 작성할 수 있습니다.

public static IEnumerable<S> DistinctBy<S, K>(this IEnumerable<S> source, Func<S, K> keySelector) {
  HashSet<K> seen = new HashSet<K>();
  foreach (S element in source) {
    if (seen.Add(keySelector(element))) {
      yield return element;
    }
  }
}

그러나 그 전에 MORELINQ를 다운로드하고 코드에 맞게 구성해야 합니다.

var q = cars.DistinctBy(p => p.id);

그런 다음 이 변수 q의 내용을 인쇄하고 답을 얻을 수 있습니다. 전체 코드는 다음과 같습니다.

using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using MoreLinq;

namespace jinlku_console {
  static class pointer {
    class CAR {
      public int id;
      public string color;

      public CAR(int id, string color) {
        this.id = id;
        this.color = color;
      }
    }

    public static IEnumerable<S> DistinctBy<S, K>(this IEnumerable<S> source,
                                                  Func<S, K> keySelector) {
      HashSet<K> seen = new HashSet<K>();
      foreach (S element in source) {
        if (seen.Add(keySelector(element))) {
          yield return element;
        }
      }
    }

    public static void Main(String[] args) {
      CAR one = new CAR(4, "red");
      CAR two = new CAR(4, "blue");
      CAR three = new CAR(6, "blue");

      List<CAR> cars = new List<CAR>();
      cars.Add(one);
      cars.Add(two);
      cars.Add(three);

      var q = cars.DistinctBy(p => p.id);

      Console.WriteLine(q.Count());

      List<CAR> distinct_c = cars.GroupBy(p => (p.id, p.color)).Select(g => g.First()).ToList();
      for (int i = 0; i < distinct_c.Count(); i++) {
        Console.Write(distinct_c[i].id + " ");
      }
    }
  }
}

C#에서 하나 이상의 속성을 기반으로 고유한 목록을 얻는 또 다른 간단한 솔루션

동일한 쿼리를 작성하는 다른 방법은 다음과 같습니다.

var un = from car in cars group car by new(car.id) into mg select mg.First();

그러나 이를 사용하려면 언어를 9.0 이상으로 업데이트해야 할 수 있습니다.

작가: Bilal Shahid
Bilal Shahid avatar Bilal Shahid avatar

Hello, I am Bilal, a research enthusiast who tends to break and make code from scratch. I dwell deep into the latest issues faced by the developer community and provide answers and different solutions. Apart from that, I am just another normal developer with a laptop, a mug of coffee, some biscuits and a thick spectacle!

GitHub

관련 문장 - Csharp LINQ