[英]Distinct of items in dictionary<T,IEnumerable<T>>
I am Looking for a cleaner way to perform the following operation: 我正在寻找一种更干净的方法来执行以下操作:
Filter out distinct values from a dictionary of type Dictionary<T,IEnumerable<T>
> , based on the uniqueness of the Value (ie unique by one of the attributes of T in the IEnumerable<T>
). 根据值的唯一性(即IEnumerable<T>
中T的属性之一来唯一),从Dictionary<T,IEnumerable<T>
类型的Dictionary<T,IEnumerable<T>
筛选出不同的值。
We can ignore the key on the dictionary. 我们可以忽略字典上的键。 Can someone suggest a good way of achieving the above ? 有人可以提出实现上述目标的好方法吗?
Jurgen Camilleri has the piece for 'SelectMany().Distinct()'. Jurgen Camilleri的作品是'SelectMany()。Distinct()'。 For the comparer, we use the following comparer all the time to compare based on a property: 对于比较器,我们一直使用以下比较器根据属性进行比较:
Usage 用法
//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));
Code 码
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;
}
}
This should work for your case: 这应该适合您的情况:
IEnumerable<T> allValues = dictionary.SelectMany((entry) => entry.Value);
IEnumerable<T> distinctValues = allValues.Distinct(comparer);
Make sure that you create a comparer class which implements IEqualityComparer<T>
so that Distinct()
can differentiate between instances of T
(unless T is a class which already has a comparer in the .NET Framework such as System.String
). 确保创建一个实现IEqualityComparer<T>
的比较器类,以便Distinct()
可以区分T
实例(除非T是在.NET Framework中已经具有比较器的类,例如System.String
)。
I wrote a method that will merge dictionaries removing duplicates. 我写了一个方法,它将合并词典以删除重复项。 Perhaps you could use the guts of this to perform something similar. 也许您可以利用此胆量来执行类似的操作。
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());
}
Maybe, just this section: 也许就是这一节:
.ToLookup(pair => pair.Key, pair => pair.Value)
.ToDictionary(group => group.Key, group => group.SelectMany(value => value).Distinct().ToList());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.