3

仮定

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);

エレガントに見えますが、機能しません。少なくとも1つのクラスの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を実行するためのより良い方法を探しているだけです。
ケン

4

4 に答える 4

5

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

申し訳ありませんが、FindAllはList<T>のメソッドです。

これ

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));
于 2010-04-07T19:19:45.460 に答える
2

リストのリストを保持するには、次の例のようにすることができます。

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<List<MyClass>>、テストに合格したMyClassオブジェクトのリストを保持します。一見すると、Selectの後にWhere拡張機能が付いているため、順序が狂っているように見えますが、内部リストの変換を最初に行う必要があります。これが、Select拡張機能で行われていることです。次に、Whereによってフィルタリングされます。

于 2010-04-07T19:42:55.373 に答える
0

私はおそらくこれで行きます

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の方法もうまく機能します:-)。

于 2010-04-07T19:40:02.947 に答える
0

フラットList<MyClass>を作成することはほとんどの場合あなたのニーズに答えますが、あなたの質問に対する正確な答えは次のとおりです。

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; }
    }
}
于 2010-04-07T20:14:52.660 に答える