LINQ: Как использовать Removeall без использования для цикла с массивом

StackOverflow https://stackoverflow.com/questions/2884403

  •  04-10-2019
  •  | 
  •  

Вопрос

В настоящее время у меня есть объект журнала, который я хотел бы удалить объекты, основанные на запросе LINQ. Я хотел бы удалить все записи в журнале, если сумма версий в программе больше 60. В настоящее время я очень уверен, что это будет работать, но кажется, что 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);
        }

Программа - это массив из 4 значений, и версия имеет массив из 3 значений. Есть ли более простой способ сделать этот Removeall в LINQ без использования петли?

Спасибо за любую помощь заранее!


РЕДАКТИРОВАТЬ:К сожалению, тип переменной, которую программа и версия основаны на выключении (что является ограничением рамок, в которой я работаю) ограничивает нас таким, что я не могу получить доступ к члену «любого». Я, однако, подтвердил, что решение Tzaman работает, если у вас есть списки Создавая некоторый пример код. Я ограничен на массивных переменных (см. Прокомментированные области)

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

  }

Спасибо Таманом!

Это было полезно?

Решение

Это должно сделать это, я думаю:

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


РЕДАКТИРОВАТЬ: Хорошо, вот как добавить методы расширения, чтобы получить IEnumerableS от ваших индексируемых «массивных» объектов, чтобы вы могли использовать Linq на них:

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

Я предполагаю MyZoneArray а также MyVersionArray Типы имеют А. Length поле, но если бы не вы могли бы просто поставить 4 а также 3 там. С этим на месте вы можете позвонить Enumerate() функция на объекте сбора, чтобы получить IEnumerable Версия коллекции, со всеми связанным linqy Goodless прилагается: log.MyZoneArray.Enumerate().Any( ... )

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top