2013-10-14 79 views
4

對於什麼是值得的,我花了一段時間看看下面的帖子,這是相關的,除了它是在多個屬性而不是兩個相同的列表上工作獨立的名單,也不涉及文本包含比較而不是項目匹配。從列表中刪除所有行,其中每行不包含任何來自另一個列表的項目

How to remove all objects from List<object> where object.variable exists at least once in any other object.variable2?

我有一個字符串列表十足的水果被稱爲「水果」

Apple 
Orange 
Banana 

我也有一個字符串列表,名爲產品,盡是些水果(加上其他雜項信息)和一些其他產品也是如此。

ShoeFromNike 
ApplePie 
OrangeDrink 

我需要從第二列表,其中每個單獨的行不字符串包含任何的水果清單所列項目的刪除所有項目。

的最終結果將是隻包含產品列表:

ApplePie 
OrangeDrink 

我最好的迭代方法:

//this fails becaucse as I remove items the indexes change and I remove the wrong items (I do realize I could reverse this logic and if it meets the criteria ADD it to a new list and i'm sure there's a better way.) 
for (int i = 0; i < products.Count(); i++) 
     { 
      bool foundMatch = false; 
      foreach (string fruit in fruits) 
       if (products[i].Contains(fruit)) 
        foundMatch = true; 

      if (foundMatch == false) 
       products.Remove(products[i]); 
     } 

我最好的LAMBDA方法:

 products.RemoveAll(p => !p.Contains(fruits.Select(f=> f))); 

回答

2

我個人喜歡使用.Any(),它似乎更適合我;

products.RemoveAll(p => !fruits.Any(f => f.IndexOf(p, StringComparison.CurrentCultureIgnoreCase) >= 0)); 
+1

是的,我認爲有一個更好的選擇,+1。應該閱讀'products.RemoveAll(p =>!fruits.Any(f => p.Contains(f)));'以符合OP。 –

+1

我很確定這不會起作用,除非'=='被覆蓋。 –

+0

@Az Za如果產品列表中的項目是Apple Orange,這不僅僅有助於嗎?換句話說,它對於包含沒有幫助。 – Kulingar

2

這裏是我的提出,可能有更好的辦法。

products.RemoveAll(p => fruits.Where(f=>p.Contains(f)).Count() == 0); 

在英語中,它讀取,刪除產品所含水果的名稱數量爲零的所有產品。

(老實說,循環可能不是那麼糟糕的一個選項,因爲它將來可能會更具可讀性)。

+0

感謝您的幫助!這是真正的贏家答案,即使我沒有使用他的索引,而是使用你的包含。 (從你對Az Za的回答的評論) – Kulingar

1

如果你想保留的循環,你也可以做你做同樣的事情,但逆轉的循環順序...

for (int i = products.Count()- 1; i >= 0; i--) 
{ 
    bool foundMatch = false; 
    foreach (string fruit in fruits) 
     if (products[i].Contains(fruit)) 
      foundMatch = true; 

    if (foundMatch == false) 
     products.Remove(products[i]); 
} 

這提前避免從名單中除名您的索引循環。

相關問題