除了价值之外,Getkey和价值

时间:2014-09-09 00:43:17

标签: c# linq

我从Dictionary< string,string>()开始,并希望从中删除其值存在于另一个List< string>中的条目。以下代码只返回一个List。删除匹配值后,可以以某种方式返回剩余键/值对的字典吗?如果没有,怎么办呢?

//pardon my pseudocode
var pNames = new Dictionary<string, string>()
{
    {key : "a1", value: "asdf_a1"},
    {key : "a2", value: "asdf_a2"},
    {key : "a3", value: "asdf_a3"}
};

var bUsers = new List<string>() { "asdf_a2" };

var nUsers = pNames.Values.Except(bUsers);
//nUsers should be a Dictionary<string,string> containing two key/value pairs:
//{key : "a1", value: "asdf_a1"},
//{key : "a3", value: "asdf_a3"}

3 个答案:

答案 0 :(得分:1)

由于您需要新字典而不是从现有字典中删除项目,因此您可以使用KeyValuePair<string,string>过滤构成字典的Where个对象,然后使用ToDictionary将结果IEnumerable<KeyValuePair<string,string>>转换回Dictionary<string,string>

的扩展方法
var nUsers = pNames
    .Where(pn => !bUsers.Contains(pn.Value)) // This will be IEnumerable<KeyValuePair<string,string>>
    .ToDictionary(x => x.Key, x => x.Value);

如果您想要不区分大小写的匹配项,请将IEqualityComparer<string>添加为Contains方法的第二个参数。

答案 1 :(得分:0)

尝试并测试

Dictionary<string, string> pNames = new Dictionary<string, string>(){
    {"a1", "asdf_a1"},
    {"a2", "asdf_a2"},
    {"a3", "asdf_a3"}
};

var bUsers = new List<string>() { "asdf_a2" };

bUsers.ForEach(user => 
{
    var Names = pNames.Where(name => name.Value == user).ToList();

    foreach (KeyValuePair<string, string> Name in Names)
        pNames.Remove(Name.Key);
});

enter image description here

答案 2 :(得分:0)

不完美。但你可以类似的东西。这种方法的好处是你可以使用任何类型。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

class Program
{
    private static void Main(string[] args)
    {
        Dictionary<string, string> pNames = new Dictionary<string, string>();
        pNames.Add("a1", "value1");
        pNames.Add("a2", "value2");
        var bUsers = new List<string>() { "value1" };

        var newKey = bUsers.ToDictionary(idx =>
        {
            return Guid.NewGuid().ToString();
        }, x => x);

        var result = pNames.Except(newKey, new CustomIEqualityComparer<string, string>());
    }

    public class CustomIEqualityComparer<TSource, TValue> : IEqualityComparer<KeyValuePair<TSource, TValue>>
    {
        public bool Equals(KeyValuePair<TSource, TValue> x, KeyValuePair<TSource, TValue> y)
        {
            return x.Value.Equals(y.Value);
        }

        public int GetHashCode(KeyValuePair<TSource, TValue> obj)
        {
            unchecked
            {
                int hash = 17;
                hash = hash * 23 + obj.Value.GetHashCode();
                return hash;
            }
        }
    }
}

如果您想使用<int, string>类型,那么它将是相同的代码:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static int index = 0;

    private static void Main(string[] args)
    {
        Dictionary<int, string> pNames = new Dictionary<int, string>();
        pNames.Add(1, "value1");
        pNames.Add(2, "value2");
        var bUsers = new List<string>() { "value1" };

        var newKey = bUsers.ToDictionary(idx =>
        {
            return index++;
        }, x => x);

        var result = pNames.Except(newKey, new CustomIEqualityComparer<int, string>());
    }

    public class CustomIEqualityComparer<TSource, TValue> : IEqualityComparer<KeyValuePair<TSource, TValue>>
    {
        public bool Equals(KeyValuePair<TSource, TValue> x, KeyValuePair<TSource, TValue> y)
        {
            return x.Value.Equals(y.Value);
        }

        public int GetHashCode(KeyValuePair<TSource, TValue> obj)
        {
            unchecked
            {
                int hash = 17;
                hash = hash * 23 + obj.Value.GetHashCode();
                return hash;
            }
        }
    }
}

您可以进一步完善和改进。