字典<t,ienumerable <t>&gt; </t,ienumerable <t>中项目的区别

时间:2015-03-13 15:16:47

标签: c# linq dictionary distinct items

我正在寻找一种更简洁的方法来执行以下操作:

从类型Dictionary<T,IEnumerable<T>&gt;的字典中过滤掉不同的值,基于价值的唯一性(即IEnumerable<T>中T的一个属性唯一)。

我们可以忽略字典上的键。有人能提出一个实现上述目标的好方法吗?

3 个答案:

答案 0 :(得分:1)

Jurgen Camilleri有'SelectMany()。Distinct()'。对于比较器,我们一直使用以下比较器来比较属性:

<强>用法

//this uses 'Product' for 'T'.  If you want to just use 'T' you'd have to constrain it

var distinctValues = dictionary.SelectMany((entry) => entry.Value)
.Distinct(new LambdaEqualityComparer<Product>(p=>p.ProductName));

<强>代码

public class LambdaEqualityComparer<T> : IEqualityComparer<T>
    {
        private Func<T,object> _action;
        public LambdaEqualityComparer(Func<T, object> action)
        {
            _action = action;
        }

        public bool Equals(T x, T y)
        {
            var areEqual = baseCheck(x, y) ?? baseCheck(getObj(x), getObj(y));

            if (areEqual != null)
            {
                return areEqual.Value;
            }

            return _action(x).Equals(_action(y));
        }

        public int GetHashCode(T obj)
        {
            return _action(obj).GetHashCode();
        }

        /// <summary>
        /// True = return true
        /// False = return false
        /// null = continue evaluating
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        private bool? baseCheck(object x, object y)
        {
            if (x == null && y == null)
            {
                return true;
            }
            else if (x == null || y == null)
            {
                return false;
            }

            return null;

        }

        private object getObj(T t)
        {
            try
            {
                return _action(t);
            }
            catch (NullReferenceException)
            {

            }

            return null;
        }
    }

答案 1 :(得分:0)

这适用于您的情况:

IEnumerable<T> allValues = dictionary.SelectMany((entry) => entry.Value);
IEnumerable<T> distinctValues = allValues.Distinct(comparer);

确保创建一个实现IEqualityComparer<T>的比较器类,以便Distinct()可以区分T的实例(除非T是已经在.NET中具有比较器的类) System.String)等框架。

答案 2 :(得分:0)

我编写了一个合并字典删除重复项的方法。也许你可以使用它的内容来执行类似的事情。

public static Dictionary<TKey, List<TValue>> MergeDictionaries<TKey, TValue>(this IEnumerable<Dictionary<TKey, List<TValue>>> dictionaries)
        {
            return dictionaries.SelectMany(dict => dict)
                         .ToLookup(pair => pair.Key, pair => pair.Value)
                         .ToDictionary(group => group.Key, group => group.SelectMany(value => value).Distinct().ToList());
        }

也许,只是这一节:

.ToLookup(pair => pair.Key, pair => pair.Value)
.ToDictionary(group => group.Key, group => group.SelectMany(value => value).Distinct().ToList());