LINQ: "contains" and a Lambda query
Solution 1
Use Any()
instead of Contains()
:
buildingStatus.Any(item => item.GetCharValue() == v.Status)
Solution 2
The Linq extension method Any could work for you...
buildingStatus.Any(item => item.GetCharValue() == v.Status)
Solution 3
Here is how you can use Contains
to achieve what you want:
buildingStatus.Select(item => item.GetCharValue()).Contains(v.Status)
this will return a Boolean value.
Solution 4
I'm not sure precisely what you're looking for, but this program:
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);
}
produces the expected output:
one: open
two: closed
four: open
five: closed
This program compares a string representation of the enum and produces the same output:
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 ();
}
I created this extension method to convert one IEnumerable to another, but I'm not sure how efficient it is; it may just create a list behind the scenes.
public static IEnumerable <TResult> ConvertEach (IEnumerable <TSource> sources, Func <TSource,TResult> convert)
{
foreach ( TSource source in sources )
yield return convert (source);
}
Then you can change the where clause to:
where statusList.ConvertEach <string> (status => status.GetCharValue()).
Contains (v.Status)
and skip creating the List<string>
with ConvertAll ()
at the beginning.
Related videos on Youtube
mark smith
Updated on September 05, 2020Comments
-
mark smith over 3 years
I have a
List<BuildingStatus>
calledbuildingStatus
. I'd like to check whether it contains a status whose char code (returned byGetCharCode()
) equals some variable,v.Status
.Is there some way of doing this, along the lines of the (non-compiling) code below?
buildingStatus.Contains(item => item.GetCharValue() == v.Status)
-
mark smith over 14 yearsThanks larry that worked, here is what i did by refering to your code... But it would be nice if possible if i didn't have to create a new list???? // Used ToList because its an ILIST and run my GetCharValue // this produces a "NEW" list with my char's var statusStringList = building.ToList().ConvertAll<char>(st => st.GetCharValue()); var test = from v in qry where statusStringList.Contains(v.Status) select v; All works, as i say it would be nice not having to do a new list or using a lambda inside Contains but appears its NOT possible?
-
XXXXX over 14 yearsI assume the status property is a string; you therefore have to convert the status enums to strings for each comparison. You might as well convert them once at the beginning and be done with it.
-
Nolonar over 8 yearsNice. I keep wondering why on Earth Linq doesn't provide a
Contains()
method, and then I realize it's supposed to beAny()
instead. +1 -
Mark Amery over 6 yearsI've made an edit that significantly simplifies the question but, in doing so, sort-of-invalidates this answer. Sorry about that, but I figured it was for the greater good overall.
-
Mark Amery over 6 years-1; while my edit to the question has slightly invalidated this answer by removing all reference to
Building
from the question, this was already really broken.foreach(Enum value in Enum.GetValues(typeof(buildingStatus)))
is nonsense. -
mohit vijay chaudhari over 3 yearshere I'm try to match my userType form user type table to user table for t collect department head name hope sa