繁体   English   中英

在C#中使列表与众不同

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM