我有一种情况,我有必须合并的对象列表。列表中的每个对象都有一个属性,用于解释在合并中应该如何处理 的方式。所以假设以下......
enum Cascade {
Full,
Unique,
Right,
Left
}
class Note {
int Id { get; set; }
Cascade Cascade { get; set; }
// lots of other data.
}
var list1 = new List<Note>{
new Note {
Id = 1,
Cascade.Full,
// data
},
new Note {
Id = 2,
Cascade.Right,
// data
}
};
var list2 = new List<Note>{
new Note {
Id = 1,
Cascade.Left,
// data
}
};
var list3 = new List<Note>{
new Note {
Id = 1,
Cascade.Unique,
// data similar to list1.Note[0]
}
}
那么,我会有一个方法......
Composite(this IList<IList<Note>> notes){
return new List<Note> {
notes.SelectMany(g => g).Where(g => g.Cascade == Cascade.All).ToList()
// Here is the problem...
.SelectMany(g => g).Where(g => g.Cascade == Cascade.Right)
.Select( // I want to do a _LastOrDefault_ )
// continuing for the other cascades.
}
}
这是我迷路的地方。我需要做多个SelectMany
语句,但我不知道如何做。但这是预期的行为。
Cascade.Full
Note
无论如何都将在最终收藏中。
Cascade.Unique
Note
将在最终集合中一次,忽略任何重复。
Cascade.Left
Note
将位于最终集合中,第一个实例将取代后续实例。 (那么,注释1,2,3是相同的。注1被推过)
Cascade.Right
Note
将位于最终集合中,最后实例将取代重复项。 (因此,注释1,2,3是相同的。注3被推低)
答案 0 :(得分:3)
我认为你应该在较小的部分分解问题。例如,您可以在单独的扩展方法中为单个列表实现级联规则。这是我对此未经测试的看法:
public static IEnumerable<Note> ApplyCascades(this IEnumerable<Note> notes)
{
var uniques = new HashSet<Note>();
Note rightToYield = null;
foreach (var n in notes)
{
bool leftYielded = false;
if (n.Cascade == Cascade.All) yield return n;
if (n.Cascade == Cascade.Left && !leftYielded)
{
yield return n;
leftYielded = true;
}
if (n.Cascade == Cascade.Right)
{
rightToYield = n;
}
if (n.Cascade == Cascade.Unique && !uniques.Contains(n))
{
yield return n;
uniques.Add(n);
}
}
if (rightToYield != null) yield return rightToYield;
}
}
此方法允许实现原始扩展方法,如下所示:
List<Note> Composite(IList<IList<Note>> notes)
{
var result = from list in notes
from note in list.ApplyCascades()
select note;
return result.ToList();
}