Frage

Im Moment habe ich ein Log-Objekt Ich mag würde Objekte entfernen, basierend auf einer LINQ-Abfrage. Ich möchte alle Datensätze im Protokoll entfernen, wenn die Summe der Versionen innerhalb eines Programms größer als 60. Derzeit ich ziemlich zuversichtlich bin, dass dies wird funktionieren, aber es scheint 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);
        }

Das Programm ist ein Array von 4 Werten und Version eine Reihe von drei Werten aufweist. Gibt es eine einfache Möglichkeit, diese RemoveAll in LINQ zu tun, ohne die for-Schleife?

Vielen Dank für jede Hilfe im Voraus!


EDIT: Leider sind die Art der Variable, dass Programm und Version aus der Basis (die eine Einschränkung des Rahmens ist in Ich arbeite) schränkt uns so, dass ich nicht das „Any“ Mitglied zugreifen kann. Ich jedoch bestätigt, dass tzaman-Lösung funktioniert, wenn Sie Listen durch einige Beispiel-Code zu erstellen. Ich bin auf Array-artige beschränkt Variablen (siehe die kommentierten Out-Bereiche)

// 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;}

  }

Danke tzaman!

War es hilfreich?

Lösung

Das sollte es tun, denke ich:

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


EDIT: Okay, so ist hier, wie Erweiterungsmethoden hinzufügen zu erhalten IEnumerables von Ihrer Wende "Array-like" Objekte, so dass Sie LINQ verwenden, um auf sie:

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]
    }
}

Ich gehe davon aus den MyZoneArray und MyVersionArray Typen ein Length Feld haben, aber wenn nicht konnte man nur in 4 und 3 dort setzen. Mit diesen vorhanden ist, können Sie jetzt die Enumerate() Funktion auf dem Sammelobjekt aufrufen, um eine IEnumerable Version der Sammlung zu bekommen, mit all der damit verbundenen LINQy Güte angehängt: log.MyZoneArray.Enumerate().Any( ... )

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top