在 List> 上使用 FindAll类型

发布于 2024-08-28 00:55:01 字数 1444 浏览 7 评论 0 原文

假设

public class MyClass
{
   public int ID {get; set; }
   public string Name {get; set; }
}

List<MyClass> classList = //populate with MyClass instances of various IDs

能做到

List<MyClass> result = classList.FindAll(class => class.ID == 123);

,这会给我一个 ID = 123 的类列表。效果很好,看起来很优雅。

现在,如果我有

List<List<MyClass>> listOfClassLists = //populate with Lists of MyClass instances

如何获得过滤列表,其中列表本身已被过滤。我尝试过

List<List<MyClass>> result = listOfClassLists.FindAll
                      (list => list.FindAll(class => class.ID == 123).Count > 0);

它看起来很优雅,但不起作用。它仅包含类列表,其中至少有一个类的 ID 为 123,但它包含该列表中的所有 MyClass 实例,而不仅仅是匹配的实例。

我最终不得不做

List<List<MyClass>> result = Results(listOfClassLists, 123);

private List<List<MyClass>> Results(List<List<MyClass>> myListOfLists, int id)
{
   List<List<MyClass>> results = new List<List<MyClass>>();
   foreach (List<MyClass> myClassList in myListOfLists)
   {
      List<MyClass> subList = myClassList.FindAll(myClass => myClass.ID == id);
      if (subList.Count > 0)
         results.Add(subList);
   }
   return results;
}

这件事来完成工作,但不是那么优雅。只是寻找更好的方法在列表列表上执行 FindAll。

Assuming

public class MyClass
{
   public int ID {get; set; }
   public string Name {get; set; }
}

and

List<MyClass> classList = //populate with MyClass instances of various IDs

I can do

List<MyClass> result = classList.FindAll(class => class.ID == 123);

and that will give me a list of just classes with ID = 123. Works great, looks elegant.

Now, if I had

List<List<MyClass>> listOfClassLists = //populate with Lists of MyClass instances

How do I get a filtered list where the lists themselves are filtered. I tried

List<List<MyClass>> result = listOfClassLists.FindAll
                      (list => list.FindAll(class => class.ID == 123).Count > 0);

it looks elegant, but doesn't work. It only includes Lists of classes where at least one class has an ID of 123, but it includes ALL MyClass instances in that list, not just the ones that match.

I ended up having to do

List<List<MyClass>> result = Results(listOfClassLists, 123);

private List<List<MyClass>> Results(List<List<MyClass>> myListOfLists, int id)
{
   List<List<MyClass>> results = new List<List<MyClass>>();
   foreach (List<MyClass> myClassList in myListOfLists)
   {
      List<MyClass> subList = myClassList.FindAll(myClass => myClass.ID == id);
      if (subList.Count > 0)
         results.Add(subList);
   }
   return results;
}

which gets the job done, but isn't that elegant. Just looking for better ways to do a FindAll on a List of Lists.
Ken

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

﹉夏雨初晴づ 2024-09-04 00:55:02

listOfClasses.SelectMany(x=>x).FindAll( /* yadda */)

抱歉,FindAll 是 List 的一种方法。

这个

var result = from x in listOfClasses from y in x where SomeCondition(y) select y;

var result = listOfClasses.SelectMany(x=>x).Where(x=>SomeCondition(x));

listOfClasses.SelectMany(x=>x).FindAll( /* yadda */)

Sorry about that, FindAll is a method of List<T>.

This

var result = from x in listOfClasses from y in x where SomeCondition(y) select y;

or

var result = listOfClasses.SelectMany(x=>x).Where(x=>SomeCondition(x));
提笔落墨 2024-09-04 00:55:02

要保留列表的列表,您可以执行类似以下示例的操作:

MyClass a = new MyClass() { ID = 123, Name = "Apple" };
MyClass b = new MyClass() { ID = 456, Name = "Banana" };
MyClass c = new MyClass() { ID = 789, Name = "Cherry" };
MyClass d = new MyClass() { ID = 123, Name = "Alpha" };
MyClass e = new MyClass() { ID = 456, Name = "Bravo" };

List<List<MyClass>> lists = new List<List<MyClass>>()
{
    new List<MyClass>() { a, b, c },
    new List<MyClass>() { d, e },
    new List<MyClass>() { b, c, e}
};

var query = lists
            .Select(list => list.Where(item => item.ID == 123).ToList())
            .Where(list => list.Count > 0).ToList();

查询将是 List> 保存通过测试的 MyClass 对象的列表。乍一看,它看起来与 Select 后面的Where 扩展不符,但内部列表的转换需要首先发生,这就是 Select 扩展中发生的情况。然后通过Where进行过滤。

To keep a list of lists, you could do something like this example:

MyClass a = new MyClass() { ID = 123, Name = "Apple" };
MyClass b = new MyClass() { ID = 456, Name = "Banana" };
MyClass c = new MyClass() { ID = 789, Name = "Cherry" };
MyClass d = new MyClass() { ID = 123, Name = "Alpha" };
MyClass e = new MyClass() { ID = 456, Name = "Bravo" };

List<List<MyClass>> lists = new List<List<MyClass>>()
{
    new List<MyClass>() { a, b, c },
    new List<MyClass>() { d, e },
    new List<MyClass>() { b, c, e}
};

var query = lists
            .Select(list => list.Where(item => item.ID == 123).ToList())
            .Where(list => list.Count > 0).ToList();

query would be List<List<MyClass>> holding lists of MyClass objects that passed the test. At first glance, it looks out of order with the Where extension coming after the Select, but the transformation of the inner lists needs to occur first, and that's what's happening in the Select extension. Then it is filtered by the Where.

旧情勿念 2024-09-04 00:55:02

我可能会采用

List<List<string>> stuff = new List<List<string>>();

List<List<string>> results = new List<List<string>>();

stuff.ForEach(list=> {var result = list.FindAll(i => i == "fun").ToList();
        if (result.Count > 0) results.Add(result);
    });

List<string> flatResult = new List<string>();

stuff.ForEach(List => flatResult.AddRange(List.FindAll(i => i == "fun")));

这种方式,您可以采用锯齿状数组或将其展平。但是 Linq 方式也效果很好:-)。

I would probably go with this

List<List<string>> stuff = new List<List<string>>();

List<List<string>> results = new List<List<string>>();

stuff.ForEach(list=> {var result = list.FindAll(i => i == "fun").ToList();
        if (result.Count > 0) results.Add(result);
    });

List<string> flatResult = new List<string>();

stuff.ForEach(List => flatResult.AddRange(List.FindAll(i => i == "fun")));

That way you can go with a jagged array or flatten it out.. But the Linq way works well too :-).

你怎么这么可爱啊 2024-09-04 00:55:02

虽然生成平面 List 将在大多数情况下满足您的需求,但您问题的准确答案是:

var result = (from list in ListOfClassLists
                          let listWithTheId=
                              (
                               (from myClass in list
                                where myClass.ID == id
                                select myClass)
                                .ToList()
                              )
                          where listWithTheId.Count > 0
                          select listWithTheId
             ).ToList();

此代码片段取自我的概念证明:

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

namespace ListOfListSelectionSpike
{
    public class ListSpikeClass
    {
        public List<List<MyClass>> ListOfClassLists { get; set; }

        private List<MyClass> list1, list2, list3;

        public ListSpikeClass()
        {
            var myClassWithId123 = new MyClass("123");
            var myClassWithIs345 = new MyClass("456");
            list1 = new List<MyClass> { myClassWithId123, myClassWithIs345 };
            list2 = new List<MyClass> { myClassWithId123, myClassWithIs345, myClassWithId123 };
            list3 = new List<MyClass> { myClassWithIs345, myClassWithIs345 };
            ListOfClassLists = new List<List<MyClass>> { list1, list2, list3 };
        }

        public List<List<MyClass>> GetListOfListsById(string id)
        {
            var result = (from list in ListOfClassLists
                          let listWithTheId =
                              ((from myClass in list
                                where myClass.ID == id
                                select myClass)
                                .ToList())
                          where listWithTheId.Count > 0
                          select listWithTheId)
                          .ToList();
            return result;
        }
    }

    public class MyClass
    {
        public MyClass(string id)
        {
            ID = id;
            Name = "My ID=" + id;
        }
        public string ID { get; set; }
        public string Name { get; set; }
    }
}

While producing a flat List<MyClass> will answer your need most of the time, the exact answer to your question is:

var result = (from list in ListOfClassLists
                          let listWithTheId=
                              (
                               (from myClass in list
                                where myClass.ID == id
                                select myClass)
                                .ToList()
                              )
                          where listWithTheId.Count > 0
                          select listWithTheId
             ).ToList();

This code snippet was taken from my Proof of Concept:

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

namespace ListOfListSelectionSpike
{
    public class ListSpikeClass
    {
        public List<List<MyClass>> ListOfClassLists { get; set; }

        private List<MyClass> list1, list2, list3;

        public ListSpikeClass()
        {
            var myClassWithId123 = new MyClass("123");
            var myClassWithIs345 = new MyClass("456");
            list1 = new List<MyClass> { myClassWithId123, myClassWithIs345 };
            list2 = new List<MyClass> { myClassWithId123, myClassWithIs345, myClassWithId123 };
            list3 = new List<MyClass> { myClassWithIs345, myClassWithIs345 };
            ListOfClassLists = new List<List<MyClass>> { list1, list2, list3 };
        }

        public List<List<MyClass>> GetListOfListsById(string id)
        {
            var result = (from list in ListOfClassLists
                          let listWithTheId =
                              ((from myClass in list
                                where myClass.ID == id
                                select myClass)
                                .ToList())
                          where listWithTheId.Count > 0
                          select listWithTheId)
                          .ToList();
            return result;
        }
    }

    public class MyClass
    {
        public MyClass(string id)
        {
            ID = id;
            Name = "My ID=" + id;
        }
        public string ID { get; set; }
        public string Name { get; set; }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文