删除字典中的重复项
本文关键字:字典 删除 | 更新日期: 2023-09-27 18:34:30
如果我有这样的字典,
Dictionary<int, string> roadNames = new Dictionary<int, string>();
roadNames.Add(1, "Rosedale Rd");
roadNames.Add(2, "Transmere Rd");
roadNames.Add(3, "Rosedale Rd");
roadNames.Add(4, "Rosedale Rd");
roadNames.Add(5, "Rosedale Rd");
roadNames.Add(6, "Rosedale Rd");
roadNames.Add(7, "Rosedale Rd");
roadNames.Add(8, "Brown Rd");
roadNames.Add(9, "Harold Rd");
是否有 LINQ 解决方案来删除彼此相邻的重复项。我追求的结果是一个包含这个的列表,
Rosedale Rd
Transmere Rd
Rosedale Rd
Brown Rd
Harold Rd
请注意,Rosedale Rd仍然在列表中两次。我们的想法是删除彼此相邻的重复项,在本例中,我们将删除第 4、5、6 和 7 项。
项目1 不在项目 3 旁边,因此不会将其删除。
更新:
不用担心字典没有被订购。有序列表的解决方案会很好。我可以处理订购。即
List<string> roadNames = new List<string>()
{
"Rosedale Rd",
"Transmere Rd",
// etc
};
假设您使用的是排序字典(或任何其他排序结构(,则有两个选项。
利用反应式扩展
如果您利用 Microsoft 的反应式扩展,这非常简单(每个人都应该这样做!
roadNames.Values // remove if a list instead
.ToObservable()
.DistinctUntilChanged()
.ToList();
如果您愿意,可以将最终ToList()
更改为ToEnumerable()
。
这将返回:
Rosedale Rd
Transmere Rd
Rosedale Rd
Brown Rd
Harold Rd
使用扩展方法
您可以按如下方式使用GroupAdjacent
扩展方法:
roadNames.Values // remove if a list instead
.GroupAdjacent((x,y) => x == y)
.Select(x => x.First());
扩展方法:
public static IEnumerable<IEnumerable<T>> GroupAdjacent<T>(
this IEnumerable<T> source, Func<T, T, bool> adjacent)
{
var g = new List<T>();
foreach (var x in source)
{
if (g.Count != 0 && !adjacent(g.Last(), x))
{
yield return g;
g = new List<T>();
}
g.Add(x);
}
yield return g;
}
下面是使用标准内置 LINQ 运算符的方法:
var result =
roadNames
.OrderBy(x => x.Key)
.Select(x => x.Value)
.Aggregate(
new List<string>(),
(xs, x) =>
{
if (xs.LastOrDefault() != x)
{
xs.Add(x);
}
return xs;
});
我假设您想在从字典中选择值之前按键排序。