[英]Concatenation of IEnumerable collections C#
我有2個Linq查詢的結果,我想使用它們執行一些字符串操作並進行連接。
結果1是從組1獲得的已啟用復選框的名稱,由
var selectedCarPosts = grpBox1MCar.Controls.OfType<CheckBox>()
.Where(c => c.Checked).OrderBy(c => c.Name).Select(c => c.Name);
結果為1:
NearMainGate
NearMP5WestGate
結果2是group2中啟用的復選框的名稱,由
var selectedDtTypeCars = gbDataTypeMCars.Controls.OfType<CheckBox>()
.Where(c => c.Checked).OrderBy(c => c.Name).Select(c => c.Name);
產生Result2:
WindDir
WindVel
從這兩個結果想得到一個串聯列表,如下所示:(Result3)
C.NearMainGate
C.NearMP5WestGate
C.WindDirNearMainGate
C.WindDirNearMP5WestGate
C.WindVelNearMainGate
C.WindVelNearMP5WestGate
這些在以后的動態sql查詢中形成列。
我有以下代碼逐步完成此操作:
var s1 = selectedCarPosts.Select(s => "C." + s); //the first 2 items in Result3
//Now to get the rest, by inserting Result2 string in each of the first 2 items of Result3
IEnumerable<string> selCarPostsArrWithC = new string[]{};
IEnumerable<string> s2 = new string[]{};
foreach (var type in selectedDtTypeCars)
{
selCarPostsArrWithC = s1.Select(s => s.Insert(2, type));//C.WindDirNearMainGate C.WindDirNearMP5WestGate in FIRST iteration and so on
s2 = s2.Concat(selCarPostsArrWithC);// as soon as the SECOND iteration starts, the previous s2 list is overwritten with the subsequent result in selCarPostsArrWithC
}
這里的問題是,在代碼調試過程中,我注意到,只要在foreach行之后點擊F10鍵,然后才實際到達foreach塊,則s2中的先前值將被selCarPostsArrWithC中的后續結果覆蓋。 解釋如下
對於第一次迭代,結果為s2。
[0] "C.WindDirNearMainGate"
[1] "C.WindDirNearMP5WestGate"
在第二次迭代的開始之前,先進入foreach塊
s2已經通過WindVel重置為新值,方法如下 :
[0] "C.WindVelNearMainGate"
[1] "C.WindVelNearMP5WestGate"
請任何人能協助我做錯了什么嗎? 如何為IEnumerable列表以粗體顯示Result3?
Enumerable.Select
在您調用它時沒有做任何重要的事情,它只是進行設置,以便稍后根據需要執行請求的工作。
所以當你寫
selCarPostsArrWithC = s1.Select(s => s.Insert(2, type));
這不會調用string.Insert
了。 僅當您(或調試器)稍后開始對selCarPostsArrWithC
迭代時才調用string.Insert
。
通常情況下,這並不重要,除非性能需要多次迭代。 但是,在這里,由於string.Insert
的調用比預期的要晚,因此傳遞給它的參數的計算也比預期的要晚。 您只有一個type
變量,並且該變量在被讀取時已經保存了下一個值。
通常,您可以通過在每次迭代中創建一個新變量來解決此問題,該變量捕獲該迭代期間看到的type
值:
foreach (var type in selectedDtTypeCars)
{
var type_ = type;
selCarPostsArrWithC = s1.Select(s => s.Insert(2, type_));
s2 = s2.Concat(selCarPostsArrWithC);
}
(現在,C#已經在foreach
幕后這樣做了,但是如果使用舊的編譯器,則可能需要這樣寫出來。)
或者,也可以直接在循環體內執行所有評估:
foreach (var type in selectedDtTypeCars)
{
selCarPostsArrWithC = s1.Select(s => s.Insert(2, type)).ToList();
s2 = s2.Concat(selCarPostsArrWithC);
}
盡管在這種情況下,最好將s2
設為List<string>
並調用其AddRange
方法。
基本上,您有一個前綴列表和一個后綴列表。 (注意:我瀏覽了您的代碼,但找不到在每個值后面附加C.
的位置。)
對於每個前綴,您都需要一個后綴。
這是SelectMany()
的用法
我簡化了代碼,因為您給出了很多代碼。 但是這是我想出的:
var location = new[]
{
"NearMainGate",
"NearMP5WestGate"
};
var modifier = new[]
{
"WindDir",
"WindVel"
};
var lambdaResult = modifier.SelectMany(s => location.Select(l => string.Format("{0}{1}{2}", "C.", s, l)));
var queryResult =
from m in modifier
from l in location
select string.Format("{0}{1}{2}", "C.", m, l);
請注意,有兩種解決方案:linq查詢語法和linq lambda語法。
在這種情況下,我認為查詢語法更簡潔易讀,但各有千秋。
這是功能證明的小提琴: https : //dotnetfiddle.net/Z61RsI
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.