2010-07-27 82 views
2

我有2个列表。我想使用LINQ来比较每个元素与这两个列表的每个元素(而不是使用一个嵌套循环)。但是,Contains不能满足我的需求,因为我需要进行自定义比较。我会想象一个自定义比较器是我需要但不是100%确定。Linq自定义比较器包含?

我不认为这应该太困难,但不能确定我需要的工具。这两个列表都包含不同类型的不同类型的对象。

更新:

对不起,如果我不清楚。我有2名列表(或可枚举),我可以做这样的事情:

foreach(item i in list1) 
    foreach(otherItemType in List2) 
    { 
    if (CompareItem(x)) do something; 
    } 

我想要做的是这样的:

var matches = myList1.Where(t => myList2.Something(t)) 

某地在何处自定义比较,或许我可以覆盖等于比较?我可以使用.Contains,但我需要做我自己的逻辑来进行比较。

更新: 我想使用IEqualityComparer,但这是设置为T,T和T,Y类型。我可以用一些通用的约束来解决这个问题。我觉得这应该很简单。

+0

你能否进一步解释你的要求,或者提供一些例子数据和预期结果? – LukeH 2010-07-27 22:13:24

+0

重写GetHashCode(),以便不同的项返回不同的哈希码,并且'相同'项返回相同的哈希码。然后包含将工作,因为它应该(我认为) – PostMan 2010-07-27 22:16:36

+0

@PostMan - 你不应该为GetHashCode()返回不同的值为不同的项目,只是它会始终返回相同的值,被认为是相等的项目。 – 2010-07-27 22:40:21

回答

2
var matches = myList1.SelectMany(
    t1 => myList2.Where(
     t2 => t2.Something(t1) 
    ) 
); 

Where就像是你内心foreach循环,外SelectMany在你的外foreach迭代循环后,通过加入的结果。

你也可以做一个函数来为你做这个(未经测试,不记得扩展语法):

public static IEnumerable<T2> MultiCompare<T1, T2>(this IEnumerable<T1> first, IEnumerable<T2> second, Func<bool, T1, T2> comparer) { 
    return first.SelectMany(
     t1 => second.Where(
      t2 => comparer(t1, t2) 
     ) 
    ); 
} 
+0

谢谢。无论如何,这样做更清楚吗?这有点难以阅读,但似乎工作。 – 2010-07-30 15:44:11

+0

@Curtis White,好的,你可以创建一个函数,就像我刚刚发布的那样。 – strager 2010-07-30 16:28:15

+0

扩展语法应该是'... MultiCompare (这个IEnumerable 首先,...'然后'first.SelectMany(...' – Jamiec 2010-07-30 16:33:06

0

我有问题here一会儿回来,可以帮助你开始。

1

如果我正确理解你的问题,下面的示例将做到这一点。由于任何需要一个委托,您可以定义列表中两个元素之间的任意匹配比较。如果您需要所有元素匹配,请使用全部代替任何

[Test] 
public void StackOverflow() 
{ 
    var digits = new int[] {1, 2, 4, 9}; 
    var strings = new string[] {"1", "4", "5", "7"}; 

    var matches = strings.Where(s => digits.Any(d => d.ToString() == s)).ToList(); 

    // Prints 
    // 1 
    // 4 

    matches.ForEach(x => System.Diagnostics.Debug.WriteLine(x)); 
} 
1

如何使用Enumerable.Join

var list = new List<int> { 1, 2, 3, 4, 5 }; 
var list2 = new List<string> { "2", "4", "5" }; 

var matches = from i in list 
       join s in list2 on i.ToString() equals s 
       select i; // if you want to use the matching items from the 1st list 

// there's no ForEach on Enumerable so you'd have to write the extension yourself (which is easy) 
// or you could just output matches to a List first 
matches.ToList().ForEach(i => Console.WriteLine(i)); 

当谈到加入我强烈希望LINQ查询语法,但你同样可以使用Lambda表达式,他们通常看起来有点乱......