Linq 从列表列表中获取特定项目

时间:2021-03-01 16:22:33

标签: c# linq

假设我有这样的对象

public class Example
{
   public List<Children> Children {get; set;}
}

public class Children
{
   public string Id {get; set;}
   public List<Element> {get; set;}
}

public class Element
{
  public string Id {get; set;}
}

所以我基本上是在做

var result1 = example.Children.where(x => x.Children.Any(y => y.Elements.Where(z => z.Id == MyId)));
var actualRes = result1.Elements.Where(x => x.Id = MyId).FirstOrDefault();

但这似乎非常低效。 任何想法如何正确地做到这一点?

谢谢!

2 个答案:

答案 0 :(得分:4)

您的代码无法编译并且存在一些错误。您可以使用 SelectMany:

var actualRes = example.Children
    .SelectMany(x => x.Elements)
    .FirstOrDefault(x => x.Id == MyId);

带有预填充示例的代码:

Example example = new(){
    Children = new()
};
for(int i=0; i < 10; i++){
    Children c = new(){
        Id = i.ToString(),
        Elements = new()
    };
    example.Children.Add(c);
    for(int j=0; j < 10; j++){
        Element e = new(){
            Id=(10*i+j).ToString()
        };
        c.Elements.Add(e);
    }
}
string MyId="23";
var result1 = example.Children
    .SelectMany(x => x.Elements)
    .FirstOrDefault(x => x.Id == MyId);

答案 1 :(得分:1)

我在编写测试用例时被@Magnetron 打败了 :-) 这个答案是他的答案的 xUnit 测试。

using System.Collections.Generic;
using System.Linq;
using Xunit;

namespace XUnitTestProject.StackOverflow
{
    public class ElementsTests
    {
        [Theory]
        [MemberData(nameof(GenerateTestData), "~element3~")]
        public void Test(Example example, string idInTest)
        {
            // we should probably use SingleOrDefault instead of FirstOrDefault
            // when dealing with instance id
            var elementToFind = example.Children
                .SelectMany(children => children.Elements)
                .FirstOrDefault(element => element.Id.Equals(idInTest));

            Assert.NotNull(elementToFind);
            Assert.Equal(idInTest, elementToFind.Id);
        }

        public static TheoryData<Example, string> GenerateTestData(string idInTest) => new()
        {
            {
                new Example()
                {
                    Children = new List<Children>
                    {
                        new()
                        {
                            Id = "~child1~", Elements = new List<Element>
                            {
                                new() {Id = "~element1~"},
                                new() {Id = "~element2~"}
                            }
                        },
                        new()
                        {
                            Id = "~child2~", Elements = new List<Element>
                            {
                                new() {Id = idInTest},
                                new() {Id = "~element4~"}
                            }
                        }
                    }
                },
                idInTest
            }
        };
    }
}
相关问题