What is the most elegant way to find index of duplicate items in C# List

限于喜欢 提交于 2019-11-30 18:48:41

You can create an object from each item containing it's index, then group on the value and filter out the groups containing more than one object. Now you have a grouping list with objects containing the text and their original index:

var duplicates = data
  .Select((t,i) => new { Index = i, Text = t })
  .GroupBy(g => g.Text)
  .Where(g => g.Count() > 1);
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++;
        }
    }
}

How about something like this

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));

I myself needed to find and remove the duplicates from list of strings. I first searched the indexes of duplicate items and then filtered the list in functional way using LINQ, without mutating the original list:

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));
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!