Lambda 表达式的行为不符合预期
本文关键字:不符合 表达式 Lambda | 更新日期: 2023-09-27 17:55:56
我正在尝试构造一个 lambda 表达式,该表达式将一个数组的元素与第二个数组的元素匹配。 下面是此查询的简化版本:
class Program
{
static void Main(string[] args)
{
string[] listOne = new string[] { "test1", "test2", "test3" };
MyClass[] listTwo = new MyClass[] { new MyClass("test1") };
string[] newVals = listOne.Where(p => listTwo.Select(e => e.Name).Equals(p)).ToArray();
//string[] newVals2 = listOne.Intersect(listTwo.Select(t => t.Name)).ToArray();
}
class MyClass
{
public MyClass(string name)
{
Name = name;
}
public string Name {get; set;}
}
}
我希望newVals
返回一个 1 值的数组,但它是空的。 我意识到取消注释 myVals2 将获得相同的结果,但类列表的差异比显示的更根本。
您正在使用Equals
但您应该使用 Contains
。您正在检查 IEnumerable<>
是否等于 p
,但您想检查IEnumerable<>
是否包含 p
,因此请替换:
string[] newVals = listOne.
Where(p => listTwo.Select(e => e.Name).Equals(p)).
ToArray();
跟
string[] newVals = listOne.
Where(p => listTwo.Select(e => e.Name).Contains(p)).
ToArray();
试试这个:
string[] listOne = new string[] { "test1", "test2", "test3" };
MyClass[] listTwo = new MyClass[] { new MyClass("test1") };
string[] newVals = listOne
.Where(p => listTwo.Select(e => e.Name).Contains(p))
.ToArray();
listTwo.Select(e => e.Name)
是一个IEnumerable<string>
您可能
希望对 2 个集合执行Join
。
var q =
listOne
.Join(
listTwo,
l2 => l2,
l1 => l1.Name,
(l2, l1) => new { l2, l1, });
您可以更改选择器(最后一个参数)以满足您的需求,例如,如果它只是 listOne 中的值,则具有 (l2, l1) => l1
.
其他解决方案将起作用,但可能不像您期望的那样。
在 where 子句中使用 Linq-Objects 包含将导致对 listOne
中的每个条目迭代整个listTwo
。
像这样的事情怎么样:
string[] newVals = listOne.Where(p => listTwo.Any(e => e.Name.Contains(p))).ToArray();
或者更严格地使用 ==
而不是 Contains
.
但是,如果您想获得两者之间共有的项目,为什么不直接调用.Intersect()
?
您正在尝试执行连接,从技术上讲,您最好简化 linq 语句以使用连接。下面包括一个示例。
static void Main(string[] args)
{
string[] listOne = new [] { "test1", "test2", "test3" };
MyClass[] listTwo = new [] { new MyClass("test1") };
string[] newVals = (from str1 in listOne
join str2 in listTwo.Select(e => e.Name) on str1 equals str2
select str1).ToArray();
foreach (var newVal in newVals)
{
Console.WriteLine(newVal);
}
//string[] newVals2 = listOne.Intersect(listTwo.Select(t => t.Name)).ToArray();
}
class MyClass
{
public MyClass(string name)
{
Name = name;
}
public string Name { get; set; }
}