Anyname Donotcare
Anyname Donotcare

Reputation: 11403

How to map 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 list of sessions like this :

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

How to map the sessions to dates considering that each date has two sessions in order(using linq).


i want the result like that :

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

Upvotes: 5

Views: 11264

Answers (5)

Raghav Thakkar
Raghav Thakkar

Reputation: 311

I think 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 several sessions. The code would look like this:

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

Upvotes: 1

brz
brz

Reputation: 6016

Here's a simple solution:

dates is a list of DateTime and sessions is a list of int.

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

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

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

Upvotes: 5

Ismail Yilmaz
Ismail Yilmaz

Reputation: 239

If you develop your project with .Net 4.0 or higher versions 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

Upvotes: 2

Andrew Whitaker
Andrew Whitaker

Reputation: 126052

Here's one way you could 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

Here's how this works:

  1. Project the dates list into a new sequence containing the index of each date and the date itself
  2. GroupJoin that collection with the list of numbers. To correlate the two, use the Index we got from step 1 for the date, and (num - 1) / 2, since Index is zero-based.
  3. To build the reusult, create a new array containing two items, one for each number associated with the date.
  4. Finally, call SelectMany to flatten the sequence.

Upvotes: 5

Fratyx
Fratyx

Reputation: 5797

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

Upvotes: 2

Related Questions