我有一個List<BuildingStatus>
稱爲buildingStatus
。我想檢查它是否包含一個狀態,其char代碼(由GetCharCode()
返回)等於某個變量v.Status
。LINQ:「包含」和一個Lambda查詢
有沒有這樣做的一些方法,沿着下面的(非編譯)代碼?
buildingStatus.Contains(item => item.GetCharValue() == v.Status)
我有一個List<BuildingStatus>
稱爲buildingStatus
。我想檢查它是否包含一個狀態,其char代碼(由GetCharCode()
返回)等於某個變量v.Status
。LINQ:「包含」和一個Lambda查詢
有沒有這樣做的一些方法,沿着下面的(非編譯)代碼?
buildingStatus.Contains(item => item.GetCharValue() == v.Status)
使用Any()
而不是Contains()
:
buildingStatus.Any(item => item.GetCharValue() == v.Status)
LINQ的擴展方法任何可以爲你工作...
buildingStatus.Any(item => item.GetCharValue() == v.Status)
我不知道正是你」重新尋找,但這個節目:
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()
。
感謝larry工作,這是我通過引用您的代碼所做的......但如果可能的話,如果我不必創建一個新的列表,這將是很好的? //使用ToList,因爲它的ILIST和運行我的GetCharValue //這將產生一個「NEW」列表和我的char的 var statusStringList = building.ToList()。ConvertAll
我假設status屬性是一個字符串;您因此必須將狀態枚舉轉換爲每個比較的字符串。你可以在開始時將它們轉換一次,然後完成它。 – XXXXX 2009-10-14 21:56:12
我做了一個大大簡化了問題的編輯,但是這樣做可以排除這個問題。對不起,但我認爲這是爲了更好的整體。 – 2018-01-23 23:02:52
如果我理解正確,您需要將在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;
}
-1;雖然我對這個問題的編輯通過從這個問題中刪除了所有關於「構建」的引用略微地使這個答案失效了,但這已經*真的被破壞了。 'foreach(Enum.GetValues中的枚舉值(typeof(buildingStatus)))'是無稽之談。 – 2018-01-23 23:08:04
這裏是你如何使用Contains
來實現你想要的:
buildingStatus.Select(item => item.GetCharValue()).Contains(v.Status)
這將返回一個布爾值。
不錯。我一直想知道Linq爲什麼不提供'Contains()'方法,然後我意識到它應該是'Any()'。 +1 – Nolonar 2015-08-18 11:39:35