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
source to share
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 theIndex
one we got from step 1 for the date and(num - 1) / 2
, since itIndex
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.
source to share
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.
}
source to share
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]));
source to share
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>>();
source to share
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
source to share