1

我有以下字典:

Dictionary<string, string> test = new Dictionary<string, string>();
test.Add("1|1", "blue");
test.Add("1|2", "Nice");
test.Add("1|3", "Jaish");
test.Add("2|2", "Muna");
test.Add("3|1", "haha");
test.Add("3|2", "green");
test.Add("4|1", "red");
Dictionary<string, string> test2 = new Dictionary<string, string>();
foreach (KeyValuePair<string, string> entry in test)
{
    if (!test2.ContainsValue(entry.Key))
        test2.Add(entry.Key, entry.Key);
}

我想删除以下重复值:

test.Add("1|2", "Nice");
test.Add("1|3", "Jaish");
test.Add("3|2", "green")

因此,删除重复项后,Dictionary的键数应为 4。

4

5 回答 5

6

假设通过管道拆分字符串的第一部分定义重复项:

var uniques = test.GroupBy(kv => kv.Key.Split('|')[0])
                  .Select(g => g.First())
                  .ToDictionary(kv => kv.Key, kv => kv.Value);

这总是选择每个组的第一个键值对。

于 2012-11-28T09:40:43.257 回答
1

实现IEqualityComparer<string>不允许您插入重复项

var test = new Dictionary<string, string>(new MyStringEqualityComparer());

...

public class MyStringEqualityComparer : IEqualityComparer<string>
{
    public bool Equals(string x, string y)
    {
        return x.Split('|')[0] == y.Split('|')[0];
    }

    public int GetHashCode(string obj)
    {
        return obj.Split('|')[0].GetHashCode();
    }
}
于 2012-11-28T09:44:00.473 回答
0

我假设|您输入键中的符号应解释为“或”。如果是这种情况,您可以先拆分键,为每个键部分生成新的键值对:

var test2 = test.SelectMany(kvp =>
    kvp.Key.Split('|').Select(k =>
        new KeyValuePair<string, string>(k, kvp.Value)));

...然后只为每个新键取第一个值:

var test3 = test2.GroupBy(kvp => kvp.Key)
                 .Select(g => g.First())
                 .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
于 2012-11-28T09:49:26.383 回答
0

If the | means OR then you can produce a new unique dictionary like this.

var oredDict = new Dictionary<int, string>();
foreach (var kv in test.ToArray())
{
    var keys = kv.Key.Split('|').Select(int.Parse);
    oredDict[keys.First() | keys.Last()] = kv.Value;
}
于 2012-11-28T10:19:19.793 回答
0

假设您的示例是人为设计的,并且您不想使用那些以管道分隔的键...

最简单的方法是不使用 Dictionary.Add(..),而只是设置值

test["1"] = "blue";
test["1"] = "NICE";
test["1"] = "Jaish";

Debug.Assert(test.Count == 1);

但是,您必须确定这是否是您想要的逻辑,它只是每次都覆盖

于 2012-11-28T09:42:50.333 回答