我有2个清单。我想使用LINQ将每个元素与两个列表的每个元素进行比较(而不是使用嵌套循环)。但是,Contains不能满足我的需求,因为我需要进行自定义比较。我认为自定义比较器是我需要的,但不是100%肯定。
我不认为这应该太难,但不确定我需要的工具。 2个列表都包含不同类型的对象。
更新
对不起,如果我不清楚的话。我有2个列表(或枚举)我可以做这样的事情:
foreach(item i in list1)
foreach(otherItemType in List2)
{
if ( CompareItem(x) ) do something;
}
我想做的是这样的事情:
var matches = myList1.Where(t => myList2.Something(t) )
Where Something是自定义比较器,也许我可以覆盖equals比较?我可以使用.Contains
,但我需要做自己的逻辑进行比较。
更新:
我想过使用IEqualityComparer
,但是它设置为采用T,T和T,Y的类型。我可以使用一些通用约束来解决这个问题。我觉得这应该简单/简单。
答案 0 :(得分: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)
)
);
}
答案 1 :(得分:1)
如果我理解你的问题,下面的示例将会这样做。由于 Any 接受委托,您可以定义列表的两个元素之间的任意匹配比较。如果您需要匹配所有元素,请使用 All 代替 Any 。
[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));
}
答案 2 :(得分: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表达式,但它们通常看起来有点混乱......
答案 3 :(得分:0)
我有一段时间的问题here可能会帮助你开始。