如何使用LINQ在C#中从另一个列表生成唯一项目的列表

4

我有一个项目列表,如下{One,Two,Three,One,Four,One,Five,Two,One},我需要一条查询语句,该语句基于唯一项目生成列表,因此返回的列表将是{One,Two,Three,Four,Five}。

8个回答

17

使用Distinct运算符:

var unique = list.Distinct();

5

3
        var x = new string[] {"One", "Two", "Three", "One", "Four", "One", "Five", "Two", "One"}.ToList();
        var distinct = x.Distinct();

2
值得注意的是,Distinct() 方法将使用默认的相等性判断方式,如果您的列表包含复杂对象而不是基元,则可能不适合您。
有一种重载方法允许您指定 IEqualityComparer 来提供自定义的相等逻辑。
关于 Distinct 如何确定两个项目是否相等的更多细节,请参见 http://msdn.microsoft.com/en-us/library/ms224763.aspx

1

使用distinct

    List<string> l = new List<string>
    {
        "One","Two","Three","One","Four","One","Five","Two","One"
    };

    var rootcategories2 = l.Distinct();

1

除了Distinct,正如其他人提到的那样,您还可以使用HashSet:

List<string> distinct = new HashSet<string>(list).ToList();

如果你正在使用LINQ,那么请使用Distinct。

0

我曾经遇到过类似的问题。我有一个importItems列表,其中包含customerName作为其中一个属性,并希望从原始列表中生成唯一客户列表。

我将原始列表传递给GenCustomers()...使用linq创建了一个itemCustomers唯一列表。然后我遍历该列表以创建新的Customer列表。

public static List<Customer> GenCustomers(List<ImportItem> importItems)
{
    List<Customer> customers = new List<Customer>();

    var itemCustomers = importItems.Select(o => new { o.CustomerName }).Distinct();

    foreach (var item in itemCustomers)
    {
        customers.Add(new Customer() { CompanyName = item.CustomerName });
    }

    return customers;
}

0

感谢您的所有答案,我想我稍微错误地表达了我的问题。实际上,我有一个复杂的类,我希望基于类的特定成员进行比较(用于Distinct)。

class ComplexClass
{
    public string Name{ get; set; }
    public string DisplayName{ get; set; }
    public int ComplexID{ get; set; }
}

List<ComplexClass> complexClassList = new List<ComplexClass>();

complexClassList.Add(new ComplexClass(){Name="1", DisplayName="One", ComplexID=1});
complexClassList.Add(new ComplexClass(){Name="2", DisplayName="Two", ComplexID=2});
complexClassList.Add(new ComplexClass(){Name="3", DisplayName="One", ComplexID=1});

// This doesn't produce a distinct list, since the comparison is Default
List<ComplexClass) uniqueList = complexClassList.Distinct();

class ComplexClassNameComparer : IEquatable<ComplexClass>
{
    public override bool Equals(ComplexClass x, ComplexClass y)
    {
        return (x.To.DisplayName == y.To.DisplayName);
    }

    public override int GetHashCode(ComplexClass obj)
    {
        return obj.DisplayName.GetHashCode();
    }
}

// This does produce a distinct list, since the comparison is specific
List<ComplexClass) uniqueList = Enumerable.Distinct(complexClassList , new ComplexClassNameComparer());

感谢那些已经指出问题的人,以及对HashSets的建议。使用具有自定义IEqualityComparer<TSource>比较器的Distinct方法起作用了。 - Steve Conlan
你应该编辑你的原始问题,而不是回答它。Stack Overflow会提示你这样做。 - Kirk Broadhurst
1
你的 ComplexClassComparerEqualsGetHashCode 的实现之间存在差异。确保返回值始终一致,目前并不明显。GetHashCode 应该返回 obj.To.DisplayName.GetHashCode() - Konrad Rudolph
谢谢Kirk,但在这种情况下,我觉得回答更准确,而不是编辑问题并使所有答案无效。 - Steve Conlan
谢谢Konrad,回答已经被编辑过了。我犯了个错误,复制/粘贴错误悄悄地溜进来了。 - Steve Conlan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接