2008-10-08 40 views
3

有沒有什麼辦法來清理這種使用LINQ的循環?如何對此進行LINQ化?

List<Car> result; 
    List<string> makes; 
    List<string> models; 

    for (int i = 0; i < makes.Count() && i < models.Count(); i++) 
    { 
    result.Add(new Car() { Make = makes[i], Model = models[i] }); 
    } 

基本上我正在尋找一些方法來將單個字段的多個數組整合到由這些字段組成的對象的單個數組中。

+0

爲什麼你還沒有一個帶2個參數的汽車的構造函數...... Make and Model ...? – 2008-10-08 17:33:30

+0

在這種情況下,我沒有一個,但這會清理一些東西。我喜歡上面的語法,因爲它允許你避免在兩個地方暴露字段。 – Luke 2008-10-08 18:00:46

回答

7

你可以使用Enumerable.Range,就像這樣:

List<Car> result = Enumerable.Range(0, Math.Min(makes.Count, models.Count)) 
    .Select(i => new Car { Make = makes[i], Model = models[i] }).ToList(); 

如果makesmodels總是包含相同數量的項目,你可以用更緊湊的語法:

List<Car> result = makes.Select((make, i) => new Car { Make = make, Model = models[i] }).ToList(); 
+0

這有效,但我希望會有更多的語法壓縮。 – Luke 2008-10-08 17:32:18

1

取決於你如何頻繁將需要編寫針對這些數組的LINQ查詢,可能值得構建一個包裝數組並實現IEnumerable<Car>的類。然後你的代碼看起來是這樣的:

IEnumerable<Car> cars = new MyClass(makes, models); 
var result = from cars... 

這不是特別複雜,建立這個;它只是四個簡單的方法(好吧,如果您計算構造函數,則有六個方法)遍佈兩個類(您還需要實現IEnumerator<Car>)。

該方法使您不必在所有LINQ查詢中嵌入實現細節。另外,如果你從來沒有這樣做,這是值得學習的東西。舒適地實施IEnumerable<T>可以顯着擴展您可以隨時使用LINQ的空間。

4

這聽起來像你真的需要一個新的LINQ操作符 - 一個沒有包含在LINQ中,有點意外:Zip。它基本上需要兩個可枚舉對象,並返回一對可配對的條目,直到完成一個或另一個原始序列。

我沒有這樣的事情,但如果你有興趣,寫作不應該花太長的時間。生成的代碼會是這樣的:

List<Car> cars = makes.Zip(models) 
         .Select(pair => new Car(pair.First, pair.Second)) 
         .ToList(); 

讓我知道如果你有興趣在此,我將它在MiscUtil編碼。

1
List<Car> result = makes 
        .Take(model.Count) 
        .Select((make, index) => new Car {Make = make, Model = models[index]}); 

請注意,這個工程即使品牌和型號是不一樣的長度。