2010-05-21 95 views
4

我目前有一個日誌對象,我想從基於LINQ查詢中刪除對象。我想刪除日誌中的所有記錄,如果在程序中版本的總和大於60。目前,我敢相信這會工作,但它似乎缺憾:LINQ:如何使用RemoveAll而不使用For循環與數組

 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個值的數組。有沒有更簡單的方法在LINQ中執行RemoveAll而不使用for循環?

感謝您提前提供任何幫助!


編輯: 不幸的是變量的那個程序和版本都基於的(這是我的工作框架的約束)的類型限制了我們這樣,我不能訪問「的任何」會員。然而,我確認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;} 

    } 

感謝tzaman!

+0

只是「任何」不起作用,或者沒有任何LINQ操作員工作?它是一個常規的'System.Array'類型,還是一些帶有重載索引操作符的自定義類型?如果是後者,你將無法使用LINQ afaik,除非你可以以某種方式從中獲得'IEnumerable'。你可以很容易地定義一個擴展方法爲你做(使用for循環和'yield return')...如果你需要一個例子,我可以更新我的答案。 – tzaman 2010-05-21 19:27:15

+0

@tzaman - 對於遲到的回覆抱歉 - 沒有任何一位操作員工作。它是一個「數組」類似的對象,我90%相信它不是系統數組類型。我現在知道它不是IEnumerable: - /。如果你知道如何創建一個IEnumerable,我將不勝感激:-) – CrimsonX 2010-05-21 22:10:00

+0

查看我更新的答案。 – tzaman 2010-05-21 23:44:28

回答

8

這應該這樣做,我想:

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


編輯:好了,所以這裏的如何添加擴展方法,從你的可轉位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] 
    } 
} 

我假設MyZoneArrayMyVersionArray類型都有一個Length領域,但如果n你可以在那裏放入43。有了這些,您現在可以調用集合對象上的Enumerate()函數來獲取集合的IEnumerable版本,並附加所有關聯的LINQy:「log.MyZoneArray.Enumerate().Any(...)

「 」
+0

嘎!對我來說太快了。好的回答:) – 2010-05-21 18:11:27

+0

Heheh。謝謝! :) – tzaman 2010-05-21 18:13:36

+0

嗯。出於某種原因,「Any」方法對我來說不適用於程序變量。您的解決方案可能正常工作,但我試圖用另一組陣列進行測試,結果無法正常工作。我認爲如果我使用列表(或者在我的實現中使用列表具有靈活性)而不是陣列,它會正常工作。 – CrimsonX 2010-05-21 18:35:30