4

現在、LINQクエリに基づいてオブジェクトを削除したいログオブジェクトがあります。プログラム内のバージョンの合計が60を超える場合は、ログ内のすべてのレコードを削除したいと思います。現在、これは機能すると確信していますが、扱いにくいようです。

        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つの値の配列があります。forループを使用せずにLINQでこのRemoveAllを実行するより簡単な方法はありますか?

事前に助けてくれてありがとう!


編集: 残念ながら、プログラムとバージョンが基づいている変数のタイプ(これは私が作業しているフレームワークの制約です)により、「Any」メンバーにアクセスできないように制限されています。ただし、サンプルコードを作成してリストがある場合は、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;}

  }

ありがとうツァマン!

4

1 に答える 1

8

これでうまくいくはずだと思います:

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


編集:さて、インデックス可能な「配列のような」オブジェクトからsを取得する拡張メソッドを追加してIEnumerable、それらで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と思いますが、そうでない場合は、あちこちに入れることができます。これらが適切に配置されたら、コレクションオブジェクトの関数を呼び出して、関連するすべてのLINQyの良さを付加したバージョンのコレクションを取得できます。MyVersionArrayLength43Enumerate()IEnumerablelog.MyZoneArray.Enumerate().Any( ... )

于 2010-05-21T18:10:24.817 に答える