【问题标题】:Select n Items from the Child List?从子列表中选择 n 个项目?
【发布时间】:2018-04-23 05:38:29
【问题描述】:

如何获取子列表的 N 个元素?假设我想为每个父母生 2 个孩子。

public class Program
{
    static void Main(string[] args)
    {
        var data = new List<Parent>()
        {
            new Parent()
            {
                Id = 1,
                Name = "ParentName1",
                Children = new List<Child>()
                {
                    new Child() { Id = 1, Name = "ChildName1"},
                    new Child() { Id = 2, Name = "ChildName2"},
                    new Child() { Id = 3, Name = "ChildName3"},
                    new Child() { Id = 4, Name = "ChildName4"},
                    new Child() { Id = 5, Name = "ChildName5"},
                }
            },
            new Parent()
            {
                Id = 2,
                Name = "ParentName2",
                Children = new List<Child>()
                {
                    new Child() { Id = 6, Name = "ChildName6"},
                    new Child() { Id = 7, Name = "ChildName7"},
                    new Child() { Id = 8, Name = "ChildName8"},
                    new Child() { Id = 9, Name = "ChildName9"},
                    new Child() { Id = 10, Name = "ChildName10"},
                }
            }
        };

        // Get only 2 child elements for parent
        var filteredData = data.Where(x => x.Children.Count >= 2)
            .ToList();


        foreach (var filteredParent in filteredData)
        {
            Console.WriteLine($"Parent {filteredParent.Id} with {filteredParent.Children.Count} children.");
        }

        Console.ReadKey();
    }
}

public class Parent
{
    public int Id { get; set; }
    public string Name { get; set; }

    public List<Child> Children { get; set; }
}

public class Child
{
    public int Id { get; set; }
    public string Name { get; set; }

    public Parent Parent { get; set; }
}

【问题讨论】:

  • data.SelectMany(x =&gt; x.Children.Take(2))
  • 试试var filteredData = data.Where(x =&gt; x.Children.Count &gt;=2).SelectMany(x =&gt; x);
  • @SlavaUtesinov:这是一个答案,而不是评论。
  • @user3261186:这是一个答案,而不是评论。这也不是OP所要求的。如果有两个以上的孩子,他们不会要求整个孩子列表;他们要求每个列表的前两个孩子。
  • @Flater 实际上,我认为 Slava 的评论也不是 OP 想要的。如果您注意到问题中代码中的 foreach 循环,您会看到 OP 正在寻找父母,但过滤掉除了每个父母的前 2 个之外的所有孩子。

标签: c# .net list linq


【解决方案1】:

一种方法是使用多语句 lambda 表达式作为结果选择器和 List&lt;T&gt; 的 RemoveRange 方法:

var query = data.Select
(
    p => 
    {
        p.Children.RemoveRange(2, p.Children.Count - 2); 
        return p;
    }
);

正如 Flater 评论的那样,返回父级的浅表副本可能会更好,只有前两个子级。这样您的查询不会更改源数据:

var query = data.Select
(
    p => new Parent() 
        {
            Id = p.Id, 
            Name = p.Name, 
            Children = p.Children.Take(2).ToList()
        }
);

【讨论】:

  • 为什么要冒着通过修改源列表产生错误的风险,而不是通过Take(2) 产生相同的结果而不修改可能在其他地方使用的数据?
  • @Flater 已编辑。
  • 为了扩展您的答案,可能需要注意的是,OP 也可以不修改列表,而只需使用 Children.Take(2) 否则他会引用 @987654327 @ 属性(例如在 foreach 中:foreach(var child in myParent.Children.Take(2))。这意味着您不必复制(这将要求您定义要复制的所有字段,这可能会导致大量琐碎的代码和/或维护问题下线)。
猜你喜欢
  • 1970-01-01
  • 2016-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-27
  • 1970-01-01
相关资源
最近更新 更多