LINQ:“包含”和一个Lambda查询


168

我有一个List<BuildingStatus>电话buildingStatus。我想检查它是否包含其字符代码(由返回GetCharCode())等于某个变量的状态v.Status

遵循下面的(非编译)代码,有某种方法可以做到这一点?

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

Answers:


320

使用Any()代替Contains()

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

13
真好 我一直在想为什么Linq上没有提供一种Contains()方法,然后我意识到应该采用这种方法Any()。+1
Nolonar 2015年

38

Linq扩展方法Any可以为您服务...

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

4

这是您可以Contains用来实现所需目标的方法:

buildingStatus.Select(item => item.GetCharValue()).Contains(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 ()开头。


谢谢拉里的工作,这是我通过参考您的代码所做的工作...但是如果我不必创建新列表,那将是很好的选择???//使用ToList,因为它是一个ILIST并运行我的GetCharValue // //生成一个“新”列表,其中包含我的char的var statusStringList = building.ToList()。ConvertAll <char>(st => st.GetCharValue()); var test =来自qry中的v,其中statusStringList.Contains(v.Status)选择v; 所有的作品,就像我说的那样,不必做一个新列表或在Contains中使用lambda会很好,但似乎不可能吗?
马克史密斯,2009年

我假设status属性是一个字符串;因此,您必须为每个比较将状态枚举转换为字符串。您最好在一开始就将它们转换一次并完成操作。
XXXXX

我进行了修改,从而大大简化了问题,但这样做会使该答案无效。抱歉,但我认为这是为了更大的整体利益。
Mark Amery

-1

如果我理解正确,则需要将“建筑物”列表中存储的类型(字符值)转换为“建筑物状态”列表中存储的类型(枚举)。

(对于建筑物列表//字符值//中的每个状态,该状态是否存在于建筑物状态列表//枚举值//中)

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;
}

-1; 虽然我对问题的编辑通过从问题中删除所有对参考的引用使此答案略有无效Building,但这已经被破坏了foreach(Enum value in Enum.GetValues(typeof(buildingStatus)))废话
Mark Amery
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.