我有一个这样的课程
class Person {
private Id;
private parentId;
private Name;
}
我有一个人的列表,看起来像这样:
List<Person> persons = new List<Person>();
persons.Add(new Person{Id =1, Name = "Andy", parentId = 0});
persons.Add(new Person{Id =2, Name = "Sandy", parentId = 0});
persons.Add(new Person{Id =3, Name = "Carter", parentId = 9});
persons.Add(new Person{Id =4, Name = "Mark", parentId = 9});
persons.Add(new Person{Id =5, Name = "Martin", parentId = 99});
persons.Add(new Person{Id =6, Name = "Matt", parentId = 99});
我想要的是:
persons.Add(new Person{Id =1, Name = "Andy", parentId = 0});
persons.Add(new Person{Id =2, Name = "Sandy", parentId = 0});
persons.Add(new Person{Id =3, Name = "Carter", parentId = 9});
persons.Add(new Person{Id =6, Name = "Matt", parentId = 99});
我希望所有人都使用parentId 0,但只选择多个分组对象中的一个。
由于
答案 0 :(得分:9)
这应该可以解决问题(似乎来自测试)。
var rootItems = persons.Where(x=>x.parentId==0);
var childItems = persons.Where(x=>x.parentId!=0).GroupBy(x=>x.parentId).Select(x=>x.First());
var requiredItems = rootItems.Concat(childItems);
它基本上分为两部分,第一部分简单地获取所有根项。第二个按父类对它们进行分组,然后选择每个组中的第一个项目。如果您想进一步细化选择哪一个,可以调整这个。
附加说明:
作为生成问题确切输出的练习,以下内容可用于childItems:
var childItems = persons.Where(x=>x.parentId!=0)
.GroupBy(x=>x.parentId)
.Select(
x=>x.OrderBy(y=>y.Id%3)
.First()
);
这显然是一种从选项中进行选择的略微荒谬的方式,但确实展示了如何通过添加某种类型的排序标准来更改选择的项目。
答案 1 :(得分:5)
要从parentId的每个分组中获取一个人,只对该值进行分组,然后从每个组中选择第一个。然后,您可以与父ID为0的人联系。
var query = people.Where(p => p.parentId == 0)
.Concat(people.Where(p => p.parentId != 0)
.GroupBy(p => p.parentId)
.Select(group => group.First()));
答案 2 :(得分:2)
假设您有一个AllPersons列表:
var parentsAdded = new HashSet<int>();
foreach(var person in AllPersons)
{
if(person.parentId == 0 || parentsAdded.Add(person.parentId))
{
persons.Add(person);
}
}
答案 3 :(得分:1)
最简单的方法是使用parentId == 0
方法使用Concat
和首先使用var results = people.Where(x => x.parentId == 0)
.Concat(persons.Where(x => x.parentId != 0)
.GroupBy(x => x.parentId)
.Select(x => x.First()))
方法合并的方法。
public static class Enumerable
{
public static IEnumerable<Person> GetFirsts(this IEnumerable<Person> source)
{
var set = new HashSet<int>();
foreach (var person in source)
{
if (person.parentId == 0 || set.Add(person.parentId))
yield return person;
}
}
}
但是,它需要两次通过集合。我建议为此编写自己的Extension方法:
var results = people.GetFirsts();
然后像这样使用它:
GetFirsts
修改强>
或public static IEnumerable<TSource> GetFirsts<TSource, TKey> (this IEnumerable<TSource> source,
Func<TSource, TKey> selector,
TKey zeroValue)
{
var set = new HashSet<TKey>();
foreach (var item in source)
{
if (selector(item).Equals(zeroValue) || set.Add(selector(item)))
yield return item;
}
}
的通用版本:
{{1}}