【问题标题】:How to map two lists using linq如何使用 linq 映射两个列表
【发布时间】:2014-12-13 01:53:41
【问题描述】:

如果我有这样的日期列表:

List<DateTime>  {5-10-2014,6-10-2014,7-10-2014}

我有这样的会话列表:

List<int>  {1,2,3,4,5,6}

考虑到每个日期有两个按顺序排列的会话(使用 linq),如何将会话映射到日期。


我想要这样的结果:

5-10-2014    1
5-10-2014    2
6-10-2014    3
6-10-2014    4
7-10-2014    5
7-10-2014    6

【问题讨论】:

  • 日期如何与会话相关联?第一个日期是否与会话列表中的前两项相关联,而第二个日期与接下来的两项相关联?

标签: c# asp.net linq list collections


【解决方案1】:

这是您可以使用GroupJoin 的一种方法:

var groupedDates = dates
    .Select((date, index) => new { Date = date, Index = index })
    .GroupJoin(
        numbers,
        dateWithIndex => dateWithIndex.Index,
        num => (num - 1) / 2,
        (dateWithIndex, nums) => new[] 
        { 
            new { Date = dateWithIndex.Date, Number = nums.First() },
            new { Date = dateWithIndex.Date, Number = nums.Last() }
        })
    .SelectMany(grp => grp);

示例: https://dotnetfiddle.net/2IIKhj

这是如何工作的:

  1. 将日期列表投影到包含每个日期索引和日期本身的新序列中
  2. GroupJoin 带有数字列表的集合。要将这两者关联起来,请使用我们从第 1 步得到的Index 作为日期,并使用(num - 1) / 2,因为Index 是从零开始的。
  3. 要构建结果,请创建一个包含两项的新数组,其中一项代表与日期关联的每个数字。
  4. 最后,调用SelectMany 将序列展平。

【讨论】:

    【解决方案2】:

    这是一个简单的解决方案:

    datesDateTime 的列表,会话是int 的列表。

    var result = sessions.Select((session,i) => 
                          new{Session = session, Date = dates[i/2]});
    

    结果包含 anonymous objects 的 IEnumerable,您可以像这样访问它的属性:

    foreach(var sessionDate in result)
    {
       var date = sessionDate.Date;
       var session = sessionDate.Session.
    }
    

    【讨论】:

    • 现在如何访问sessions列表中的日期,我的意思是在那之后查询sessions的内容是什么
    • 在评论之前先尝试一下。
    【解决方案3】:

    假设 listi.Length == 2*listd.Length

    List<int> listi = new int[] { 1, 2, 3, 4, 5, 6 }.ToList();
    List<DateTime> listd = new DateTime[] { DateTime.Parse("5-10-2014"), DateTime.Parse("6-10-2014"), DateTime.Parse("7-10-2014") }.ToList();
    
    IEnumerable<Tuple<DateTime, int>> result = 
        Enumerable.Range(0, listi.Count)
        .Select(x => new Tuple<DateTime, int>(listd[x / 2], listi[x]));
    

    【讨论】:

      【解决方案4】:

      如果您使用 .Net 4.0 或更高版本开发项目,则可以使用 Zip()。

      IEnumerable<int> keys = new List<int>() { 1, 2, 3, 4, 5, 6 }; // your keys
      IEnumerable<DateTime> values = new List<DateTime>() { DateTime.Parse("5 - 10 - 2014"), DateTime.Parse("6 - 10 - 2014"), DateTime.Parse("7 - 10 - 2014") }; // your values
      var mappedDictionary = keys.Zip(values, (k, v) => new {
                  k,
                  v
              }).ToDictionary(x => x.k, x => x.v);
      

      这个链接证明了它是如何工作的.. https://dotnetfiddle.net/yKYf8S

      【讨论】:

      • 我很确定这不会得到他想要的结果
      • 让我们给他一个拍摄的机会;)
      【解决方案5】:

      我认为在 C# 中映射值的最佳方法是使用 Dictionary&lt;Key,Value&gt;。您可以有一对多的关系——也就是说,一个日期有几个会话。代码如下所示:

      Dictionary<DateTime, List<int>> dicDateSesstion = new Dictionary<DateTime, List<int>>();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-15
        • 2017-10-23
        • 1970-01-01
        • 1970-01-01
        • 2012-06-19
        • 1970-01-01
        • 2015-02-10
        • 1970-01-01
        相关资源
        最近更新 更多