LINQ: How to Use RemoveAll without using For loop with Array
I currently have a log object I'd like to remove objects from, based on a LINQ query. I would like to remove all records in the log if the sum of the versions within a program are greater than 60. Cu开发者_JS百科rrently I'm pretty confident that this'll work, but it seems kludgy:
for (int index = 0; index < 4; index++)
{
Log.RemoveAll(log =>
(log.Program[index].Version[0].Value +
log.Program[index].Version[1].Value +
log.Program[index].Version[2].Value ) > 60);
}
The Program is an array of 4 values and version has an array of 3 values. Is there a more simple way to do this RemoveAll in LINQ without using the for loop?
Thanks for any help in advance!
EDIT: Unfortunately the type of variable that Program and Version are based off of (which is a constraint of the framework I'm working in) restricts us such that I cannot access the "Any" member. I however confirmed that tzaman's solution works if you have lists by creating some sample code. I'm restricted to array-like variables (see the commented out areas)
// I'm restricted to Arrays, but if I had lists, this would work.
internal class MyLogCollection
{
List<MyLog> MyListOfZones = new List<MyLog>();
public void TestRemove()
{
// Original Implementation
for (int i = 0; i < 4; i++)
{
MyListOfZones.RemoveAll(log => (log.MyZoneArray[0].MyVersionArray[0].Value +
log.MyZoneArray[0].MyVersionArray[1].Value +
log.MyZoneArray[0].MyVersionArray[2].Value) > 60);
//"Any" method is not available off of intellisense scope on MyZoneArray
}
// Better Implementation (thanks tzaman!)
MyListOfZones.RemoveAll(log => (log.MyZoneArray.Any(prog =>
prog.MyVersionArray.Sum(ver => ver.Value) > 60)));
}
}
internal class MyLog
{
//public MyZone[] MyZoneArray = new MyZone[4];
public List<MyZone> MyZoneArray = new List<MyZone>(4);
}
internal class MyZone
{
//public MyVersion[] MyVersionArray = new MyVersion[3];
public List<MyVersion> MyVersionArray = new List<MyVersion>(3);
}
internal class MyVersion
{
public byte Value { get; set;}
}
Thanks tzaman!
This should do it, I think:
Log.RemoveAll(log =>
log.Program.Any(prog =>
prog.Version.Sum(ver => ver.Value) > 60));
EDIT: Okay, so here's how to add extension methods to get IEnumerable
s from your indexable "array-like" objects, so that you can use LINQ on them:
static class MyExtensions
{
public static IEnumerable<MyZone> Enumerate(this MyZoneArray zone)
{
for (int i = 0; i < zone.Length; i++)
yield return zone[i];
}
public static IEnumerable<MyVersion> Enumerate(this MyVersionArray version)
{
for (int i = 0; i < version.Length; i++)
yield return version[i]
}
}
I'm assuming the MyZoneArray
and MyVersionArray
types have a Length
field, but if not you could just put in 4
and 3
over there. With these in place, you can now call the Enumerate()
function on the collection object to get an IEnumerable
version of the collection, with all the associated LINQy goodness attached: log.MyZoneArray.Enumerate().Any( ... )
精彩评论