[英]Making a list distinct in C#
在C#中,我有一个对象类型'A',其中包含键值对列表。
键值对是类别字符串和值字符串。
要实例化对象类型A,我将必须执行以下操作:
List<KeyValuePair> keyValuePairs = new List<KeyValuePair>();
keyValuePairs.Add(new KeyValuePair<"Country", "U.S.A">());
keyValuePairs.Add(new KeyValuePair<"Name", "Mo">());
keyValuePairs.Add(new KeyValuePair<"Age", "33">());
A a = new A(keyValuePairs);
最终,我将得到一个A对象类型的列表,并且我想操纵该列表,以便仅获得唯一值,并且仅基于国家/地区名称。 因此,我希望列表减少为仅包含一个“国家”,“美国”,即使它出现了不止一次。
我一直在研究linq Distinct,但是它并没有实现我想要的功能,因为它无法定义任何参数,并且因为它似乎无法捕获两个等效的A型对象。我知道可以覆盖“等于”方法,但是它仍然不能解决我的问题,即基于一个键值对使列表与众不同。
为了扩展卡尔·安德森(Karl Anderson)关于使用morelinq的建议,如果您无法(或不想)为您的项目链接到另一个dll,我不久前就实现了这一点:
public static IEnumerable<T> DistinctBy<T, U>(this IEnumerable<T> source, Func<T, U>selector)
{
var contained = new Dictionary<U, bool>();
foreach (var elem in source)
{
U selected = selector(elem);
bool has;
if (!contained.TryGetValue(selected, out has))
{
contained[selected] = true;
yield return elem;
}
}
}
用法如下:
collection.DistinctBy(elem => elem.Property);
在支持它的.NET版本中,可以使用HashSet<T>
代替Dictionary<T, Bool>
,因为我们实际上并不关心该值有多少,因为它已经被哈希了。
您需要首先选择与众不同的属性:
因为它是列表中的列表,所以可以使用SelectMany。 SelectMany将合并子选择的结果。
List<A> listOfA = new List<A>();
listOfA.SelectMany(a => a.KeyValuePairs
.Where(keyValue => keyValue.Key == "Country")
.Select(keyValue => keyValue.Value))
.Distinct();
应该是这样。 它将选择键为“国家/地区”的所有值,并合并列表。 最终它将与国家不同。 假定类A的属性KeyValuePairs至少为IEnumerable <KeyValuePair <字符串,字符串>>
在morelinq项目中检查DistinctBy
语法。
A a = new A(keyValuePairs);
a = a.DistinctBy(k => new { k.Key, k.Value }).ToList();
var result = keyValuePairs.GroupBy(x => x.Key)
.SelectMany(g => g.Key == "Country" ? g.Distinct() : g);
您可以使用groupby语句。 在这里,您可以进行各种出色的工作
listOfA.GroupBy(i=>i.Value)
您可以将值分组,然后将所有键或其他有用的东西相加
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.