How to match two lists using linq

If I have a list of dates like this:

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

      


and I have a list of sessions like this:

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

      


How do I map sessions to dates, given that each date has two sessions in order (using linq).


I want the result:

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

      

+3


source to share


5 answers


Here's one way to do it with 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);

      

Example: https://dotnetfiddle.net/2IIKhj



This is how it works:

  • List the dates into a new sequence containing the index of each date and the date itself
  • GroupJoin

    this collection is a list of numbers. To correlate these two values, use the Index

    one we got from step 1 for the date and (num - 1) / 2

    , since it Index

    is zero-based.
  • To create a reusult, create a new array containing two elements, one for each number associated with the date.
  • Finally, call SelectMany

    to flatten the sequence.
+2


source


Here's a simple solution:

dates

is a list DateTime

and sessions are a list int

.

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

      



The result contains IEnumerable of anonymous objects , you can access its properties like this:

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

      

+4


source


Listi.Length == 2 * listd.Length is assumed

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

      

+2


source


I think the best way to map values โ€‹โ€‹in C # is to use Dictionary<Key,Value>

. You can have a one-to-many relationship, that is, one date has multiple sessions. The code will look like this:

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

      

+1


source


If you are developing your project with .Net 4.0 or later, you can use 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);

      

This link proves how it works. https://dotnetfiddle.net/yKYf8S

0


source







All Articles