2009-10-14 59 views
121

我有一個List<BuildingStatus>稱爲buildingStatus。我想檢查它是否包含一個狀態,其char代碼(由GetCharCode()返回)等於某個變量v.StatusLINQ:「包含」和一個Lambda查詢

有沒有這樣做的一些方法,沿着下面的(非編譯)代碼?

buildingStatus.Contains(item => item.GetCharValue() == v.Status) 

回答

232

使用Any()而不是Contains()

buildingStatus.Any(item => item.GetCharValue() == v.Status) 
+6

不錯。我一直想知道Linq爲什麼不提供'Contains()'方法,然後我意識到它應該是'Any()'。 +1 – Nolonar 2015-08-18 11:39:35

30

LINQ的擴展方法任何可以爲你工作...

buildingStatus.Any(item => item.GetCharValue() == v.Status) 
3

我不知道正是你」重新尋找,但這個節目:

public class Building 
    { 
     public enum StatusType 
     { 
      open, 
      closed, 
      weird, 
     }; 

     public string Name { get; set; } 
     public StatusType Status { get; set; } 
    } 

    public static List <Building> buildingList = new List<Building>() 
    { 
     new Building() { Name = "one", Status = Building.StatusType.open }, 
     new Building() { Name = "two", Status = Building.StatusType.closed }, 
     new Building() { Name = "three", Status = Building.StatusType.weird }, 

     new Building() { Name = "four", Status = Building.StatusType.open }, 
     new Building() { Name = "five", Status = Building.StatusType.closed }, 
     new Building() { Name = "six", Status = Building.StatusType.weird }, 
    }; 

    static void Main (string [] args) 
    { 
     var statusList = new List<Building.StatusType>() { Building.StatusType.open, Building.StatusType.closed }; 

     var q = from building in buildingList 
       where statusList.Contains (building.Status) 
       select building; 

     foreach (var b in q) 
      Console.WriteLine ("{0}: {1}", b.Name, b.Status); 
    } 

產生預期的輸出:

one: open 
two: closed 
four: open 
five: closed 

該程序比較枚舉的字符串表示,併產生相同的輸出:

public class Building 
    { 
     public enum StatusType 
     { 
      open, 
      closed, 
      weird, 
     }; 

     public string Name { get; set; } 
     public string Status { get; set; } 
    } 

    public static List <Building> buildingList = new List<Building>() 
    { 
     new Building() { Name = "one", Status = "open" }, 
     new Building() { Name = "two", Status = "closed" }, 
     new Building() { Name = "three", Status = "weird" }, 

     new Building() { Name = "four", Status = "open" }, 
     new Building() { Name = "five", Status = "closed" }, 
     new Building() { Name = "six", Status = "weird" }, 
    }; 

    static void Main (string [] args) 
    { 
     var statusList = new List<Building.StatusType>() { Building.StatusType.open, Building.StatusType.closed }; 
     var statusStringList = statusList.ConvertAll <string> (st => st.ToString()); 

     var q = from building in buildingList 
       where statusStringList.Contains (building.Status) 
       select building; 

     foreach (var b in q) 
      Console.WriteLine ("{0}: {1}", b.Name, b.Status); 

     Console.ReadKey(); 
    } 

我建立這個擴展方法來將一個IEnumerable轉換爲另一個IEnumerable,但我不確定它的效率如何;它可能只是在幕後創建一個列表。

public static IEnumerable <TResult> ConvertEach (IEnumerable <TSource> sources, Func <TSource,TResult> convert) 
{ 
    foreach (TSource source in sources) 
     yield return convert (source); 
} 

然後你可以在WHERE子句更改爲:

where statusList.ConvertEach <string> (status => status.GetCharValue()). 
    Contains (v.Status) 

,並跳過開頭創建List<string>ConvertAll()

+0

感謝larry工作,這是我通過引用您的代碼所做的......但如果可能的話,如果我不必創建一個新的列表,這將是很好的? //使用ToList,因爲它的ILIST和運行我的GetCharValue //這將產生一個「NEW」列表和我的char的 var statusStringList = building.ToList()。ConvertAll (st => st。GetCharValue()); var test = from q in qry where statusStringList.Contains(v.Status) select v; 所有的作品,正如我所說,它會很好,不必做一個新的列表或在包含內使用lambda表達式,但出現它不可能? – 2009-10-14 15:12:49

+0

我假設status屬性是一個字符串;您因此必須將狀態枚舉轉換爲每個比較的字符串。你可以在開始時將它們轉換一次,然後完成它。 – XXXXX 2009-10-14 21:56:12

+0

我做了一個大大簡化了問題的編輯,但是這樣做可以排除這個問題。對不起,但我認爲這是爲了更好的整體。 – 2018-01-23 23:02:52

-1

如果我理解正確,您需要將在Building列表中存儲 的類型(char值)轉換爲您在buildingStatus列表中存儲的類型(枚舉)。

(在建築列表//字符值//每個狀態, 確實在buildingStatus列表中的狀態存在//枚舉值//)

public static IQueryable<Building> WithStatus(this IQueryable<Building> qry, 
     IList<BuildingStatuses> buildingStatus) 
    { 
     return from v in qry 
       where ContainsStatus(v.Status) 
       select v;   
    } 


private bool ContainsStatus(v.Status) 
{ 
foreach(Enum value in Enum.GetValues(typeof(buildingStatus))) 
{ 
    If v.Status == value.GetCharValue(); 
    return true; 
} 
return false; 
} 
+0

-1;雖然我對這個問題的編輯通過從這個問題中刪除了所有關於「構建」的引用略微地使這個答案失效了,但這已經*真的被破壞了。 'foreach(Enum.GetValues中的枚舉值(typeof(buildingStatus)))'是無稽之談。 – 2018-01-23 23:08:04

0

這裏是你如何使用Contains來實現你想要的:

buildingStatus.Select(item => item.GetCharValue()).Contains(v.Status)這將返回一個布爾值。