2015-04-04 45 views
1

我有一個Linq查詢的結果,我想用它做一些字符串操作和連接。IEnumerable集合的並置C#

結果1,其是從組1啓用複選框的名,由

var selectedCarPosts = grpBox1MCar.Controls.OfType<CheckBox>() 
.Where(c => c.Checked).OrderBy(c => c.Name).Select(c => c.Name); 

其產率結果1中得到:

NearMainGate 
NearMP5WestGate 

結果2是啓用的複選框從組2的名稱,obtainedby

var selectedDtTypeCars = gbDataTypeMCars.Controls.OfType<CheckBox>() 
.Where(c => c.Checked).OrderBy(c => c.Name).Select(c => c.Name); 

產生結果2:

WindDir 
WindVel 

從兩個結果想獲得一個連續清單如下:(Result3)在動態SQL查詢後

C.NearMainGate 
C.NearMP5WestGate 
C.WindDirNearMainGate 
C.WindDirNearMP5WestGate 
C.WindVelNearMainGate 
C.WindVelNearMP5WestGate 

這些表格列。

我有以下的代碼來完成這一步一步:

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 
} 

這裏的問題是,代碼調試過程中,我注意到,那隻要我點擊F10鍵只在foreach線後,前實際上達到了foreach塊,s2中的先前值將被selCarPostsArrWithC中的後續結果覆蓋。下面解釋

對於第一次迭代s2有結果。

[0] "C.WindDirNearMainGate" 
[1] "C.WindDirNearMP5WestGate" 

在第二次迭代開始時進入的foreach塊內

S2之前已經重置爲新值與WindVel一些如何:

[0] "C.WindVelNearMainGate" 
[1] "C.WindVelNearMP5WestGate" 

請可以在任何一個幫助我算什麼我做錯了?我怎樣才能完成粗體的Result3,爲IEnumerable列表?

回答

0

基本上你有一個前綴列表和一個後綴列表。 (注意:我瀏覽了你的代碼,並且我找不到在每個值附加的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

+0

嗨,卡梅隆!哇這真棒。 (upvote需要15分,現在只有7分,我很快就達到了15分我會這樣做)現在我意識到我對LINQ有多瞭解。需要了解更多LINQ語法,以及掌握C# 。 (你可能已經理解我已經是一個新的蜜蜂了);-)你的lambda和查詢結果都像一個魅力。你可以建議好的書籍,LINQ和C#中的Winforms編程資源?對不起主題。 – Nish 2015-04-04 17:04:28

+0

@Nish有**噸**資源。我個人從工作代碼看最好。 [MSDN的Linq資源](https://msdn.microsoft.com/en-us/library/bb397926.aspx)是偉大的。如果您想要代碼示例,Microsoft有[101 LInq示例](https://代碼。 msdn.microsoft.com/101-LINQ-Samples-3fb9811b)來查看。 – Cameron 2015-04-04 17:58:39

+0

謝謝Cameron。說得通。是啊!祝你有美好的一天 – Nish 2015-04-04 18:58:33

1

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 a List<string>,並調用其AddRange方法。

+0

嗨hvd。感謝您的信息..我試圖解決方案形式卡梅隆..它的工作。但是,仍然感謝。您的評論回答了我的代碼爲什麼不起作用。很多LINQ的東西要學:-)。 – Nish 2015-04-04 18:57:13