1

C# には 2 つのリストがあります。

public class AvailableSlot
{
     public DateTime DateTime;
     public string Name
}

 List<AvailableSlot> list1 = GetList();
 List<AvailableSlot> list2 = GetAnotherList();

これらのリストで intersect を呼び出して、同じ日付の両方のリストのどこにアイテムがあるかを調べたいと思います。.Intersect を使用してこの情報を取得できることはわかっていますが、もう少し複雑な要件があります。交差したリストを返したいのですが、このリストにすべての名前を含むオブジェクトのリストを含めたいです。このようなもの:

  List<AvailableSlot2> intersectedList  . ..

ここで、AvailableSlot2 は以下のとおりです。

public class AvailableSlot2
{
     public DateTime DateTime;
     public string[] Names;
}

2 つのリスト間で交差しようとした後に、この変換を行う機能はありますか?

4

3 に答える 3

2

2つのリストを結合し、DateTimeでグループ化してから、グループから名前を引き出します。

var list1 = new List<AvailableSlot>
{
    new AvailableSlot { DateTime = new DateTime(2013, 2, 1), Name = "Alpha" },
    new AvailableSlot { DateTime = new DateTime(2013, 2, 2), Name = "Bravo" },
    new AvailableSlot { DateTime = new DateTime(2013, 2, 3), Name = "Charlie" },
    new AvailableSlot { DateTime = new DateTime(2013, 2, 1), Name = "Delta" },
    new AvailableSlot { DateTime = new DateTime(2013, 2, 2), Name = "Echo" },
    new AvailableSlot { DateTime = new DateTime(2013, 2, 3), Name = "Foxtrot" },
    new AvailableSlot { DateTime = new DateTime(2013, 2, 4), Name = "Golf" },
    new AvailableSlot { DateTime = new DateTime(2013, 2, 5), Name = "Hotel" }
};

var list2 = new List<AvailableSlot>
{
    new AvailableSlot { DateTime = new DateTime(2013, 2, 1), Name = "Apple" },
    new AvailableSlot { DateTime = new DateTime(2013, 2, 2), Name = "Bannana" },
    new AvailableSlot { DateTime = new DateTime(2013, 2, 1), Name = "Dog" },
    new AvailableSlot { DateTime = new DateTime(2013, 2, 2), Name = "Egg" },
    new AvailableSlot { DateTime = new DateTime(2013, 2, 5), Name = "Hi" }
};

var list3 = list1.Where (l => list2.Where (li => l.DateTime == li.DateTime).Any ())
   .Union(list2.Where (l => list1.Where (li => l.DateTime == li.DateTime).Any ()));

var groupedItems = from slot in list3
    group slot by slot.DateTime into grp
    select new AvailableSlot2 {
        DateTime = grp.Key,
        Names = grp.Select (g => g.Name).ToArray()
    };

foreach(var g in groupedItems)
{
    Console.WriteLine(g.DateTime);
    foreach(var name in g.Names)
        Console.WriteLine(name);
    Console.WriteLine("---------------------");
}

出力:

2/1/2013 12:00:00 AM
Alpha
Delta
Apple
Dog
---------------------
2/2/2013 12:00:00 AM
Bravo
Echo
Bannana
Egg
---------------------
2/5/2013 12:00:00 AM
Hotel
Hi
---------------------
于 2013-02-16T18:48:15.217 に答える
0

ToLookupを利用できます:

DateTime dt1 = new DateTime(2013, 2, 1);
DateTime dt2 = new DateTime(2013, 3, 1);
DateTime dt3 = new DateTime(2013, 4, 1);

var list1 = new List<AvailableSlot>
{
    new AvailableSlot{DateTime = dt1, Name = "n1",},
    new AvailableSlot{DateTime = dt2, Name = "n2",},
    new AvailableSlot{DateTime = dt1, Name = "n3",},
};

var list2 = new List<AvailableSlot>
{
    new AvailableSlot{DateTime = dt1, Name = "n1",},
    new AvailableSlot{DateTime = dt2, Name = "n2",},
    new AvailableSlot{DateTime = dt3, Name = "n3",},
};

var intersected = list1.Select (l => l.DateTime).
                        Intersect(list2.Select (l => l.DateTime));

var lookup = list1.Union(list2).ToLookup (
                                slot => slot.DateTime, slot => slot);

lookup.Where (l => intersected.Contains(l.Key)).Select (
    slot => new 
    {
        DateTime=slot.Key, 
        Names=slot.Select (s => s.Name)
    });

この場合、結果は次のようになります。

DateTime            Names

01/02/2013 00:00    n1
                    n3
                    n1

01/03/2013 00:00    n2
                    n2

もちろん、 Names=slot.Select(s => s.Name).Distinct() を使用して、名前の個別のリストを取得できます。

于 2013-02-16T20:02:46.910 に答える
0

LINQ to ObjectsJoin()を使用して、同じ DateTime プロパティを持つ項目を並べてから、すべての名前を配列に収集できます。

var joinedItems = from slot1 in list1
                  join slot2 in list2
                  on slot1.DateTime equals slot2.DateTime into g
                  where g.Any()
                  select new AvailableSlot2
                  {
                      DateTime = slot1.DateTime,
                      Names = Enumerable.Range(slot1.Name,1).Union(g.Select(s => s.Name)).ToArray()
                  }
于 2013-02-16T18:30:43.390 に答える