2010-04-27 10 views
8

중복이 포함 된 List<string>이 있는데 각 인덱스를 찾아야합니다.C# List에서 중복 항목의 인덱스를 찾는 가장 우아한 방법은 무엇입니까

모든 항목을 반복하는 것 외에 가장 우아하고 효율적인 방법은 무엇입니까? .NET 4.0에서 LINQ 옵션을 사용할 수 있습니다. 나는 수 많은 검색과 연결을 한 결과 아무것도 찾았습니다.

샘플 데이터 :

var data = new List<string>{"fname", "lname", "home", "home", "company"}(); 

나는 "집"의 인덱스를 얻을 필요가있다.

+11

: 내가 먼저 원래 목록을 돌연변이없이, LINQ 사용하여 기능적인 방법으로 목록을 필터링 한 후 중복 항목의 인덱스를 검색하고? 분류 되었습니까? 그것은 분류가 가능한가? 평등을 어떻게 비교하고 있습니까? 어떤 데이터 유형이나 문자열에 대해서만 작동해야합니까? 왜 당신은 처음에 목록에 중복을 넣고 있습니까? 당신은 가장 우아하고 가장 효율적인 것을 요구했지만 그 반대의 경우가 많습니다. 실제로 더 중요한 것인가? –

+1

왜 "항목을 반복하는 것 외에"라고 말하고 있습니까? 누군가는 어떤 시점에서 항목을 반복해야합니다 - 당신이나 linq 이건 상관 없지만 상관 없습니다. – Stewart

답변

19

인덱스가 포함 된 각 항목에서 개체를 만든 다음 값을 그룹화하고 두 개 이상의 개체가 포함 된 그룹을 필터링 할 수 있습니다. 이제 텍스트를 포함하는 객체와 원래 인덱스 그룹화 목록을 가지고 :

var duplicates = data 
    .Select((t,i) => new { Index = i, Text = t }) 
    .GroupBy(g => g.Text) 
    .Where(g => g.Count() > 1); 
+0

나는이 해결책을 좋아한다! 읽기 쉽고 빠릅니다! –

+0

감사합니다. 내가 찾을 수있는 가장 우아한 해결책이었습니다. –

3
using System; 
using System.Collections.Generic; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var data = new List<string> { "fname", "lname", "home", "home", "company" }; 
     foreach (var duplicate in FindDuplicates(data)) 
     { 
      Console.WriteLine("Duplicate: {0} at index {1}", duplicate.Item1, duplicate.Item2); 
     } 
    } 

    public static IEnumerable<Tuple<T, int>> FindDuplicates<T>(IEnumerable<T> data) 
    { 
     var hashSet = new HashSet<T>(); 
     int index = 0; 
     foreach (var item in data) 
     { 
      if (hashSet.Contains(item)) 
      { 
       yield return Tuple.Create(item, index); 
      } 
      else 
      { 
       hashSet.Add(item); 
      } 
      index++; 
     } 
    } 
} 
0

어떻게 자신을 발견하고 목록에서 중복을 제거하기 위해 필요한이

var data = new List<string>{"fname", "lname", "home", "home", "company"}; 

      var duplicates = data 
          .Select((x, index) => new { Text = x, index}) 
          .Where(x => ( data 
              .GroupBy(i => i) 
              .Where(g => g.Count() > 1) 
              .Select(g => g.Key).ToList() 
             ).Contains(x.Text)); 
+0

Interresting, 그러나 매우 비효율적입니다. 목록의 각 항목에 대해 한 번 대신 조회를 생성해야합니다. 효율적으로 검색하려면 List가 아니라 HashSet이어야합니다. – Guffa

0

같은 약 문자열. 목록에 얼마나 많은 항목

public static IEnumerable<string> RemoveDuplicates(IEnumerable<string> items) 
{ 
    var duplicateIndexes = items.Select((item, index) => new { item, index }) 
          .GroupBy(g => g.item) 
          .Where(g => g.Count() > 1) 
          .SelectMany(g => g.Skip(1), (g, item) => item.index); 
    return items.Where((item, index) => !duplicateIndexes.Contains(index)); 
} 
관련 문제