2014-11-05 70 views
0

我有两个相同对象的列表,我想基于不区分大小写的方式查找这些列表的联合和交集对象属性的比较。如何在linq中以不区分大小写的方式比较字符串,它们是对象的属性

为简单起见,我们将其称为Person,并且我想过滤Person.Name属性。

这样做的建议方法是什么?我希望将代码保存在Linq的一行中。

目前我做了以下内容:

public class Person { public string Name { get; set; } } 

-

var people = 
    firstListOfPeople.Where(
     p1 => p1.Name != null && 
      secondListOfPeople 
       .Where(p2 => p2.Name != null) 
       .Select(p2 => p2.Name.ToUpper()) 
       .Contains(p1.Name.ToUpper())); 
+1

看起来'Select.Contains'有点超过顶部;但否则代码似乎是合理的。该代码是否会导致问题? – BradleyDotNET 2014-11-05 00:06:48

+0

对于等于 - http://stackoverflow.com/questions/3121957/how-can-i-do-a-case-insensitive-string-comparison,为包含 - IndexOf:http://stackoverflow.com/questions/444798/case-insensitive-containsstring ...不能使两者都重复:) – 2014-11-05 00:06:59

+0

@BradleyDotNET不,代码有效。只是希望更简单一些(即使这意味着扩展Person类),如:'firstListOfPeople.Intersect(secondListOfPeople)' – 2014-11-05 00:08:57

回答

1

我认为@BradleyDotNET有正确的答案,但因为我已经有一个例子大多是完整的,我想我会张贴在情况下,它可以帮助某人在路上:

void Main() 
{ 
    var firstListOfPeople = new[] 
    { 
     new Person { Name = "Rufus" }, 
     new Person { Name = "Bob" }, 
     new Person { Name = "steve" }, 
    }; 

    var secondListOfPeople = new[] 
    { 
     new Person { Name = "john" }, 
     new Person { Name = "Bob" }, 
     new Person { Name = "rufus" }, 
    }; 

    var people = firstListOfPeople.Intersect(secondListOfPeople, new PersonNameComparer()); 

    people.Dump(); // displays the result if you are using LINQPad 
} 

public class Person 
{ 
    public string Name { get; set; } 
} 

public class PersonNameComparer: EqualityComparer<Person> 
{ 

    public override bool Equals(Person p1, Person p2) 
    { 
     return p1.Name.Equals(p2.Name, StringComparison.OrdinalIgnoreCase); 
    } 

    public override int GetHashCode(Person p) 
    { 
     return p.Name.ToLower().GetHashCode(); 
    } 
} 
4

您可以向下塌陷您的代码如下:

firstListOfPeople.Intersect(secondListOfPeople); 

渔获自带的病例对名称不敏感的比较。 Intersect使用默认的相等比较器(引用相等),所以您需要实现IEqualityComparer<T>MSDN)。

该比较可以进行基于名称的比较。然后,您可以创建一个并把它传递给Intersect正确的过载:http://msdn.microsoft.com/en-us/library/vstudio/bb355408(v=vs.100).aspx

firstListOfPeople.Instersect(secondListOfPeople, myComparer); 
+0

太棒了,我认为这是正确的道路。不幸的是,这个类已经有一个自定义的比较器,它比我所需要的要多(它做了更深入的比较,例如'Age'属性也是如此)。但这听起来像我可以通过一个不同的。让我试试看。 – 2014-11-05 00:16:15

+0

@PeterDuniho,你可以使用'Comparer '作为'Intersect()'吗?我不认为'Comparer '是'IEqualityComparer ',因此它不匹配'Intersect()'的签名(第二次重载)。 – devuxer 2014-11-05 01:09:28

+0

@devuxer:你是对的,我忘了'Comparer '只实现'IComparer ',而不是'IEqualityComparer '(事后看来,它是完全没有意义的)。没有散​​列码的实现,这里没有用。 (但在我看来,.NET应该有一个'EqualityComparer .Create()'方法:))。 – 2014-11-05 01:22:21

相关问题