我有一个包含重复项的List<string>
,我需要找到每个的索引。
除了循环遍历所有项目之外,最优雅,最有效的方法是什么。我在.NET 4.0上,所以LINQ是一个选项。我做了大量的搜索并连接找到任何东西。
示例数据:
var data = new List<string>{"fname", "lname", "home", "home", "company"}();
我需要获得“home”的索引。
答案 0 :(得分:20)
您可以从包含其索引的每个项目创建一个对象,然后对该值进行分组并过滤掉包含多个对象的组。现在,您有一个分组列表,其中包含包含文本及其原始索引的对象:
var duplicates = data
.Select((t,i) => new { Index = i, Text = t })
.GroupBy(g => g.Text)
.Where(g => g.Count() > 1);
答案 1 :(得分: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++;
}
}
}
答案 2 :(得分: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));
答案 3 :(得分:0)
我自己需要从字符串列表中查找并删除重复项。我首先搜索重复项的索引,然后使用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));
}