LINQ: using RemoveAll without using a for loop with array

Currently, I have a log object from which I want to delete objects based on a LINQ query. I would like to delete all entries in the log if the sum of the versions in the program is more than 60. Currently, I'm pretty sure that this will work, but it looks like 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 the version has an array of 3 values. Is there an easier way to do this RemoveAll in LINQ without using a for loop?

Thanks for any help in advance!


EDIT: Unfortunately, the type of variable that the program and version is associated with (which is a limitation of the scope in which I work) limits us to not being able to access the Any element. However, I confirmed that the tzaman solution works if you have lists by creating some sample code. I will limit myself to array variables (see sections with comments)

 // 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!

+4
source share
1 answer

That should do it, I think:

 Log.RemoveAll(log => log.Program.Any(prog => prog.Version.Sum(ver => ver.Value) > 60)); 


EDIT: So, here's how to add extension methods to get IEnumerable from your array-indexable objects so you can use LINQ for 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 assume that the types MyZoneArray and MyVersionArray have a Length field, but if not, you can just put 4 and 3 there. With their help, you can now call the Enumerate() function in the collection object to get the IEnumerable collection version, with all LINQy bindings connected to it: log.MyZoneArray.Enumerate().Any( ... )

+8
source

Source: https://habr.com/ru/post/1310542/


All Articles