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

尝试在两个列表之间相交后是否有能力进行这种转换?

4

3 回答 3

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

您可以使用 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 回答
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 回答