在 C# List 中查找重复项索引的最优雅方法是啥

Posted

技术标签:

【中文标题】在 C# List 中查找重复项索引的最优雅方法是啥【英文标题】:What is the most elegant way to find index of duplicate items in C# List在 C# List 中查找重复项索引的最优雅方法是什么 【发布时间】:2011-02-12 17:06:40 【问题描述】:

我有一个包含重复项的 List<string>,我需要找到每个的索引。

除了遍历所有项目之外,最优雅、最有效的方法是什么。我在 .NET 4.0 上,所以 LINQ 是一个选项。我已经进行了大量的搜索和连接找到任何东西。

样本数据:

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

我需要获取“家”的索引。

【问题讨论】:

列表中有多少项?排序了吗?是否可排序?你如何比较平等?它必须适用于任何数据类型还是只适用于字符串?您为什么首先将重复项放在列表中?你要求最优雅和最有效的,但这些往往是相反的;哪个更重要? 你为什么说“除了遍历项目”?有人必须在某个时候循环遍历这些项目——无论是你还是 linq 都肯定是无关紧要的。 【参考方案1】:

您可以从包含它的索引的每个项目创建一个对象,然后对值进行分组并过滤掉包含多个对象的组。现在您有了一个分组列表,其中包含包含文本及其原始索引的对象:

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

【讨论】:

谢谢,这是我能找到的最优雅的解决方案【参考方案2】:
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++;
        
    

【讨论】:

【参考方案3】:

这样的事情怎么样

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

【讨论】:

很有趣,但效率很低。您应该为列表中的每个项目创建一次查找,而不是一次。为了提高效率,查找应该是 HashSet,而不是 List。【参考方案4】:

我自己需要从字符串列表中查找并删除重复项。我首先搜索重复项的索引,然后使用 LINQ 以功能方式过滤列表,而不改变原始列表:

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

【讨论】:

以上是关于在 C# List 中查找重复项索引的最优雅方法是啥的主要内容,如果未能解决你的问题,请参考以下文章

C#确定列表中的重复项[重复]

通过聚合在pandas组中查找频繁项的最有效方法是啥[重复]

在c#中使用lambda或linq查找项目索引[关闭]

从 C# 中的 List<T> 中删除重复项

进行这种递归多对多数据库查找的最优雅方法是啥?

使用 C# 在复杂的 JSON 数组中查找和打印重复项