Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 删除字典中的重复项_C#_.net - Fatal编程技术网

C# 删除字典中的重复项

C# 删除字典中的重复项,c#,.net,C#,.net,如果我有一本这样的字典 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, "Rosedal

如果我有一本这样的字典

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");
请注意,罗斯代尔路仍在列表中两次。我们的想法是删除彼此相邻的重复项,在本例中,我们将删除第4、5、6和7项

项目1不在项目3的旁边,因此它不会被删除

更新:

不要担心字典没人订购。一个有序的列表的解决方案就可以了。我可以处理订货。i、 e

List<string> roadNames = new List<string>()
{
    "Rosedale Rd",
    "Transmere Rd",
    // etc
};
List roadNames=新列表()
{
“罗斯代尔路”,
“Transmere路”,
//等
};

假设您使用的是排序字典(或任何其他排序结构),则有两个选项

利用被动扩展功能

如果你利用微软(每个人都应该这么做!),这是非常简单的:

如果愿意,您可以将final
ToList()
改为
ToEnumerable()

这将返回:

Rosedale Rd 
Transmere Rd 
Rosedale Rd 
Brown Rd 
Harold Rd 
使用扩展方法

您可以使用如下扩展方法:

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;
}
公共静态IEnumerable组(
此IEnumerable源,Func(相邻)
{
var g=新列表();
foreach(源中的变量x)
{
如果(g.Count!=0&&!相邻(g.Last(),x))
{
收益率g;
g=新列表();
}
g、 加(x);
}
收益率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;
            });
var结果=
路名
.OrderBy(x=>x.Key)
.选择(x=>x.Value)
.合计(
新列表(),
(xs,x)=>
{
if(xs.LastOrDefault()!=x)
{
xs.Add(x);
}
返回xs;
});

我假设您希望在从字典中选择值之前按键排序。

您不能。字典是无序的。我想不出用LINQ做这件事的任何方法(除了
Aggregate()
hacking)我也在研究类似于Aggregate的东西,或者更多的LINQ.batch你想要LINQ解决方案的原因是什么?看起来,一个纯LINQ解决方案将比一个不受LINQ限制的解决方案更困难、更混乱,而且可能更慢。只是优雅而已。如果LINQ是困难的,我愿意接受所有的解决方案。我使用的扩展方法非常有效。“我真的不想使用反应式扩展。@peter-为什么这被标记为解决方案,因为这两个选项都不能满足您在问题中的要求?”?
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;
}
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;
            });