我有列表,我;只想使用 LinQ/LAMBDA 根据某些标准进行选择
我的代码是
Lists.ForEach(x => x.IsAnimal == false { /* Do Something */ } );
我在这部分收到错误“只有赋值、调用、递增、递减和新对象表达式可以用作语句” x.IsAnimal == false
我知道我们可以通过 for 循环轻松实现这一点,但我想通过使用 LinQ/LAMBDA 了解更多信息
在使用 ForEach 之前使用Where和ToList
Lists.Where(x => !x.IsAnimal).ToList().ForEach(...)
那是行不通的,因为你不能拥有false{}
构造。
Lists.ForEach(x => {
if(x.IsAnimal){
//Do Something
}
} );
请阅读 lambda 表达式的语法: lambda 表达式代表一个方法;前面的部分=>
是参数列表,后面的部分要么是返回结果的单个表达式,要么是方法体。
您可以在该方法主体中添加您的限制:
Lists.ForEach(x => {
if (!x.IsAnimal) {
// do something
}
});
应该是这样的:
things.Where(x => !x.IsAnimal).ToList().ForEach(x => { // do something });
我可以看到人们抱怨必须建立新列表才能使用 ForEach。你可以用 Select 做同样的事情并坚持使用 IEnumerable:
things.Where(x => !x.IsAnimal).Select(x =>
{
// do something with it
return x; // or transform into something else.
});
请记住, lists.foreach 和普通的 foreach 之间是有区别的。每个“正常”都使用枚举器,因此更改迭代的列表是非法的。lists.foreach() 不使用枚举器(如果我没记错的话,它在后台使用索引器),因此可以随时更改数组中的项目。
希望这可以帮助
如果你想在不同类型的集合上使用“ForEach”,你应该为 IEnumerable 编写一个扩展:
public static class IEnumerableExtension
{
public static void ForEach<T>(this IEnumerable<T> data, Action<T> action)
{
foreach (T d in data)
{
action(d);
}
}
}
使用此扩展程序,您可以在使用 ForEach 之前进行过滤,并且不必使用过滤后的项目形成新列表:
lists.Where(x => !x.IsAnimal).ForEach( /* Do Something */ );
我更喜欢标准版:
foreach (var x in lists.Where(x => !x.IsAnimal)) { /* Do Something */ }
不是很长,很明显是一个有副作用的循环。
试试这样的代码:
class A {
public bool IsAnimal { get; set; }
public bool Found { get; set; }
}
class Program
{
static void Main(string[] args)
{
List<A> lst = new List<A>();
lst.Add(new A() { IsAnimal = false, Found = false });
lst.Add(new A() { IsAnimal = true, Found = false });
lst.Add(new A() { IsAnimal = true, Found = false });
lst.Add(new A() { IsAnimal = false, Found = false });
// Here you first iterate to find only items with (IsAnimal == false)
// then from IEnumerable we need to get a List of items subset
// Last action is to execute ForEach on the subset where you can put your actions...
lst.Where(x => x.IsAnimal == false).ToList().ForEach(y => y.Found = true);
}
}