将 3 个不同类型的列表合并为一个新的列表类型
Merge 3 different type lists in one new list type
具有以下模型(为简单起见,我发布了界面)。
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;}
}
到目前为止我已经尝试过但似乎卡住了如何 select 每个转换列表的属性。
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"
.
的对应值
可以使用 joins 将多个列表按共同标准合并。
如果您只想要 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
)或缺少长度(更改连接顺序),除非您想要真正的完整外部连接,即您 期望 any 长度,斜率和评级不包含另一个集合中存在的类别。然后创建所有类别的列表并左外连接视图模型:
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
});
具有以下模型(为简单起见,我发布了界面)。
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;}
}
到目前为止我已经尝试过但似乎卡住了如何 select 每个转换列表的属性。
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"
.
可以使用 joins 将多个列表按共同标准合并。
如果您只想要 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
)或缺少长度(更改连接顺序),除非您想要真正的完整外部连接,即您 期望 any 长度,斜率和评级不包含另一个集合中存在的类别。然后创建所有类别的列表并左外连接视图模型:
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
});