2009-10-14 89 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)这将返回一个布尔值。