C# LINQ,选择多个可能的结果
我有一种情况,我有一个必须合并的对象列表。列表中的每个对象都有一个属性,用于解释在合并中应如何处理该对象。因此,假设如下C# LINQ,选择多个可能的结果,c#,linq,C#,Linq,我有一种情况,我有一个必须合并的对象列表。列表中的每个对象都有一个属性,用于解释在合并中应如何处理该对象。因此,假设如下 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 No
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]
}
}
enum级联{
满满的,
独特的,
正确的,
左边
}
课堂笔记{
int Id{get;set;}
级联{get;set;}
//还有很多其他的数据。
}
var list1=新列表{
新注释{
Id=1,
瀑布,全部,
//资料
},
新注释{
Id=2,
对,
//资料
}
};
var list2=新列表{
新注释{
Id=1,
瀑布,左边,
//资料
}
};
var list3=新列表{
新注释{
Id=1,
独特的,
//与列表1类似的数据。注[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.
}
}
Composite(此IList注释){
返回新列表{
notes.SelectMany(g=>g).Where(g=>g.Cascade==Cascade.All).ToList()
//问题是。。。
.SelectMany(g=>g)。其中(g=>g.Cascade==Cascade.Right)
.Select(//我想做一个_LastOrDefault)
//继续进行其他级联。
}
}
这就是我迷路的地方。我需要执行多个SelectMany
语句,但我不知道如何执行。但这是预期的行为
Cascade.Full
无论发生什么情况,注释
都将出现在最终收藏中
Cascade.Unique
注释
将在最终集合中出现一次,忽略任何重复项
Cascade.Left
注释
将在最终集合中,第一个实例将取代后续实例。(因此,注释1、2、3是相同的。注释1被推过)
Cascade.Right
注释
将在最终集合中,最后一个实例替换重复项。(所以注释1、2、3是相同的。注释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;
}
}
公共静态IEnumerable ApplyCascades(此IEnumerable注释)
{
var uniques=new HashSet();
注意rightToYield=null;
foreach(注释中的变量n)
{
bool=false;
如果(n.Cascade==Cascade.All)收益率返回n;
if(n.Cascade==Cascade.Left&&!Left)
{
收益率n;
左=真;
}
如果(n.Cascade==Cascade.Right)
{
rightToYield=n;
}
如果(n.Cascade==Cascade.Unique&!uniques.Contains(n))
{
收益率n;
添加(n);
}
}
如果(rightoyield!=null)收益返回rightoyield;
}
}
此方法允许实现如下原始扩展方法:
List<Note> Composite(IList<IList<Note>> notes)
{
var result = from list in notes
from note in list.ApplyCascades()
select note;
return result.ToList();
}
列表组合(IList注释)
{
var result=来自notes中的列表
来自list.ApplyCascades()中的注释
选择注释;
返回result.ToList();
}
我发现,当LINQ方式不是很明显时,用“长”方式编写代码通常很有帮助。通过这样做,您可以对所有细节进行排序,并得到一个有效的解决方案。然后LINQ版本变得更容易推理。是否有必要保留注释的顺序,或者您只是在寻找结果列表,而不管顺序如何?顺序并不重要,只是在最终编译中是否存在正确的注释。而且您没有奇怪的边缘情况?比如1,Unique/1,Right(哪一个赢了?反过来也是一样,1,Left/1,Unique?那么1,Left/1,Right呢?),这比使用linq语句解决这个问题要好得多。但是我认为您需要if(n.Cascade==Cascade.Unique&&!uniques.Add(n))
instead@Magnus谢谢,修复了(需要将注释添加到HashSet中)谢谢,这已经足够好了。但是,我很失望,它不能在一个LINQ查询中完成。