2016-11-19 35 views
-1

具有以下模型(爲了簡化,我發佈了這些接口)。在一個新的列表類型中合併3個不同的類型列表

public class LengthViewModel 
{ 
    public int Length { get; set; } 
    public string Category { get; set; } 
} 

public class SlopeViewModel 
{ 
    public int Slope { get; set; } 
    public string Category { get; set; } 
} 

public class RatingViewModel 
{ 
    public double Rating { get; set; } 
    public string Category { get; set; } 
} 

然後我在另一個ViewModel中有一個ObservableCollection的每個類型。

public ObservableCollection<LengthViewModel> Lengths { get; set; } 
public ObservableCollection<SlopeViewModel> Slopes { get; set; } 
public ObservableCollection<RatingViewModel> Ratings { get; set; } 

我需要將上述列表轉換爲一個列表,下面是它應該創建的新列表類型。

public ObservableCollection<LengthSlopeRatingViewModel> Aggregate { get; set; } 

public class LengthSlopeRatingViewModel 
{ 
    public string Category { get; set; } 
    public int Length { get; set; } 
    public int Slope { get; set; } 
    public double Rating { get; set;} 
} 

我到目前爲止的嘗試,但似乎堅持如何選擇每個轉換列表的屬性。

var lengths = Lengths.Select(p => new LengthSlopeRatingViewModel 
{ 
    Category = p.Category, 
    Length = p.Length 
}); 

var slopes = Slopes.Select(p => new LengthSlopeRatingViewModel 
{ 
    Category = p.Category, 
    Slope = p.Slope 
}); 

var ratings = Ratings.Select(p => new LengthSlopeRatingViewModel 
{ 
    Category = p.Category, 
    Rating = p.Rating 
}); 

// Concat and group them, then select new type again with the properties? 
CourseRatings = lengths.Concat(slopes) 
    .Concat(ratings) 
    .GroupBy(p => p.Category) 
    .Select(g => g.ToList()) 
    .As<IEnumerable<LengthSlopeRatingViewModel>>() 
    .ToObservableCollection(); 

例如,如果您有長度,坡度和評級,Category = "Black"Category = "Blue"另一個實例的實例,我應該得到LengthSlopeRatingViewModel的兩個實例,一個與Category = "Black"和第一場比賽的相應值和一個與Category = "Blue"

+0

不應該'選擇'後'GroupBy'是'SelectMany'? – KMoussa

+1

在提出問題時,請花更多的努力來設置代碼的格式 - 不需要將其大部分縮小到正確的位置。我這次編輯了這個問題。這聽起來像你真正想要的是幾個連接,說實話......你應該也說出你想要發生什麼,如果這個類別只在一個或兩個原始集合中。 –

+0

我承認它需要更多的工作來解決這個問題,現在我看到了這個連接,我被卡住了一點,感謝編輯:-) –

回答

2

通過一個共同標準組合多個列表可以使用join s完成。

如果你想有一個LengthSlopeRatingViewModel結果,只有當所有集合包含對應一個類別項目:

Aggregate = new ObservableCollection<LengthSlopeRatingViewModel>(
    from l in Lengths 
    join s in Slopes on l.Category equals s.Category 
    join r in Ratings on s.Category equals r.Category 
    select new LengthSlopeRatingViewModel { 
     Category = l.Category, 
     Length = l.Length, 
     Slope = s.Slope, 
     Rating = r.Rating 
    }); 

如果如一些評級缺少,你仍然希望與違約評級的列表:

Aggregate = new ObservableCollection<LengthSlopeRatingViewModel>(
    from l in Lengths 
    join s in Slopes on l.Category equals s.Category 
    join r in Ratings on s.Category equals r.Category into ratings 
    from r in ratings.DefaultIfEmpty() 
    select new LengthSlopeRatingViewModel { 
     Category = l.Category, 
     Length = l.Length, 
     Slope = s.Slope, 
     Rating = r?.Rating ?? 0 
    }); 

前者等同於:

Aggregate = new ObservableCollection<LengthSlopeRatingViewModel>(
    Lengths 
    .Join(Slopes, _ => _.Category, _ => _.Category, 
     (l, s) => new LengthSlopeRatingViewModel 
      { Category = l.Category, Length = l.Length, Slope = s.Slope }) 
    .Join(Ratings, _ => _.Category, _ => _.Category, 
     (ls, r) => { ls.Rating = r.Rating; return ls; })); 

這些應該是很容易適應其他使用情況如缺失斜率(加DefaultIfEmpty)或缺少長度(改變連接順序),除非你想要一個真正的全外連接,即你期望長度,斜率和等級的任何不包含另一個集合中存在的類別。然後創建一個所有類別的列表和左外連接視圖模型的作品:

var categories = 
    Lengths.Select(_ => _.Category).Concat(
    Slopes.Select(_ => _.Category)).Concat(
    Ratings.Select(_ => _.Category)) 
    .Distinct(); 

Aggregate = new ObservableCollection<LengthSlopeRatingViewModel>(
    from c in categories 
    join l in Lengths on c equals l.Category into lengths 
    from l in lengths.DefaultIfEmpty() 
    join s in Slopes on c equals s.Category into slopes 
    from s in slopes.DefaultIfEmpty() 
    join r in Ratings on c equals r.Category into ratings 
    from r in ratings.DefaultIfEmpty() 
    select new LengthSlopeRatingViewModel 
    { 
     Category = c, 
     Length = l?.Length ?? 0, // or any other default 
     Slope = s?.Slope ?? 0, 
     Rating = r?.Rating ?? 0 
    }); 
+0

感謝您的詳細解答,正是我需要的! –

相關問題