I'm looking for a way to update an Element in a List without enumerating it on my own.
I got the Class MyProjects which hold a List named Projects.
I want to find the MyProjects.Projects-Class, where a member property of Class1 (Name) equals the Value "Overhead".
What works:
foreach (Project prj in MyProjects.Projects) {
if (prj.Name == "Overhead")
prj.IsActive = true;
};
I, however, try to do the same by using Linq, but failed in writing it as one line. Is this even possible? The reason why I don't like to iterate in the way above is that I already iterate the whole list in this codeblock and think, that there might be a more beautiful way :)
You shouldn't try to get everything down to one line - just as brief as is readable. In this case, you can use:
foreach (var project in MyProjects.Projects.Where(p => p.Name == "Overhead"))
{
project.IsActive = true;
}
That's using LINQ for the querying part, which is appropriate as that's what the Q of LINQ stands for. I'd strongly urge you not to mutate items within LINQ calls in the way that Mayank's answer does though. It's error-prone (as evidenced by the original answer not working) and against the spirit of LINQ.
That's about as readable as it gets, IMO. It does exactly the same thing as the original code, mind you - you can't avoid something iterating over every item in the list, if every item might be one you want to update.
EDIT: Just for laughs, if you really, really wanted to do it in pretty minimal code, you could use:
// DON'T USE THIS!
MyProjects.Project.Count(p => p.Name == "Overhead" && (p.IsActive = true));
Here we use the fact that &&
is short-circuiting to avoid evaluating the assignment (p.IsActive = true
) unless the condition is matched. It's handy that we're assigning a bool
value to a property, as that means we don't need to do anything else to make it a valid second operand for the &&
operator. We use Count()
to fully evaluate the result without creating any additional lists etc - and we use the version with a predicate to avoid even needing a Where
call, which a previous version did. (LastOrDefault
would work too.) But it's all a horrible abuse, and should never appear in any real code.
See more on this question at Stackoverflow