假设我有以下课程。
class Foo
{
public int Id { get; set; }
public List<Foo> Children { get; set; }
}
以及以下ID数组
int[] ids = new int[] { 1, 3, 5 };
以及以下两个对象
var myParentChildrenMatchesFoo = new Foo
{
Id = 1,
Children = new List<Foo>
{
new Foo {
Id = 3,
Children = null
},
new Foo {
Id = 2,
Children = null
},
new Foo {
Id = 5,
Children = null
}
}
};
var myParentNoMatchesFoo = new Foo
{
Id = 2,
Children = new List<Foo>
{
new Foo {
Id = 3,
Children = null
},
new Foo {
Id = 2,
Children = null
},
new Foo {
Id = 5,
Children = null
}
}
};
var myChildrenNoMatchesFoo = new Foo
{
Id = 1,
Children = new List<Foo>
{
new Foo {
Id = 2,
Children = null
},
new Foo {
Id = 4,
Children = null
},
new Foo {
Id = 6,
Children = null
}
}
};
var myNoMatchesFoo = new Foo
{
Id = 1,
Children = new List<Foo>
{
new Foo {
Id = 2,
Children = null
},
new Foo {
Id = 4,
Children = null
},
new Foo {
Id = 6,
Children = null
}
}
};
如果子节点匹配但子节点不匹配且仅返回匹配的子节点,如何根据我的ids数组的交集返回匹配记录?
预期结果:
myParentChildrenMatchesFoo { Id: 1, Children: [{ Id: 3, Children: []}, { Id: 5, Children: []}] }
myParentNoMatchesFoo { Id: 1, Children: [{ Id: 3, Children: []}, { Id: 5, Children: []}] }
myChildrenNoMatchesFoo { Id: 1, Children: [] }
myNoMatchesFoo { }
这是我目前的方向。我将所有内容添加到列表中,以便我可以使用Linq。
List<Foo> myFoo = new List<Foo>();
myFoo.Add(myChildrenNoMatchesFoo);
myFoo.Add(myNoMatchesFoo);
myFoo.Add(myParentChildrenMatchesFoo);
myFoo.Add(myParentNoMatchesFoo);
我正在使用.SelectMany的重载来搜索子项并展平对象。
var test = myFoo
.SelectMany(c => c.Children, (parent, child) => new { parent = parent, child = child }).Where(c => ids.Contains(c.child.Id))
.Select(p => new Foo()
{
Id = p.parent.Id,
Children = new List<Foo>() { p.child }
})
.ToList();
然后我可以.GroupBy将父ID重新组合在一起,但似乎应该有更好的方法。我知道我可以很容易地在两个嵌套循环中构建一个新对象,或者我可以创建一个帮助扩展,它可以做我想要的但是我试图找到一个只有Linq的方法,如果没有其他原因而不是看到如果可以的话。
答案 0 :(得分:0)
显然下面的代码有效。它令人难以置信的丑陋和难以理解。我会向后工作,看看我是否可以清理它或简化它。
var wow = myFoo
.SelectMany(c => c.Children, (parent, child) => new { parent = parent, child = child })
.Where(p => ids.Contains(p.parent.Id) || ids.Contains(p.child.Id))
.Select(p => new
{
Id = p.parent.Id,
Children = p.child
})
.GroupBy(g => g.Id, (key, group) => new { Id = key, group = group.Select(g => g.Children) })
.Select(g => new
{
Id = g.Id,
Children = g.group.Where(c => ids.Contains(c.Id)).ToList()
}).ToList();