Reputation: 71
I have two arrays, array1 has datetime data count by minute from 8am to 2pm and array2 has datetime data count by hour from same date 8am to 1pm.
I want to output the index number of two array that has same datetime.hour. and it should matchup the last available index number of array2 for all of the datetime data from array1 that later than array2.
for example if I have two datetime array like this:
DateTime[] dateTimes1 = new DateTime[]
{
new DateTime(2010, 10, 1, 8, 15, 0),
new DateTime(2010, 10, 1, 8, 30, 1),
new DateTime(2010, 10, 1, 8, 45, 2),
new DateTime(2010, 10, 1, 9, 15, 3),
new DateTime(2010, 10, 1, 9, 30, 4),
new DateTime(2010, 10, 1, 9, 45, 5),
new DateTime(2010, 10, 1, 10, 15, 6),
new DateTime(2010, 10, 1, 10, 30, 7),
new DateTime(2010, 10, 1, 10, 45, 8),
new DateTime(2010, 10, 1, 11, 15, 9),
new DateTime(2010, 10, 1, 11, 30, 10),
new DateTime(2010, 10, 1, 11, 45, 11),
new DateTime(2010, 10, 1, 12, 15, 12),
new DateTime(2010, 10, 1, 12, 30, 13),
new DateTime(2010, 10, 1, 12, 45, 14),
new DateTime(2010, 10, 1, 13, 15, 15),
new DateTime(2010, 10, 1, 13, 30, 16),
new DateTime(2010, 10, 1, 13, 45, 17),
new DateTime(2010, 10, 1, 14, 15, 18),
new DateTime(2010, 10, 1, 14, 30, 19),
new DateTime(2010, 10, 1, 14, 45, 20),
};
DateTime[] dateTimes2 = new DateTime[]
{
new DateTime(2010, 10, 1, 8, 0, 0),
new DateTime(2010, 10, 1, 9, 0, 1),
new DateTime(2010, 10, 1, 10, 0, 2),
new DateTime(2010, 10, 1, 11, 0, 3),
new DateTime(2010, 10, 1, 12, 0, 4),
new DateTime(2010, 10, 1, 13, 0, 5),
};
it should gives me the output:
0, 0
1, 0
2, 0
3, 1
4, 1
5, 1
6, 2
7, 2
8, 2
9, 3
10, 3
11, 3
12, 4
13, 4
14, 4
15, 5
16, 5
17, 5
18, 5
19, 5
20, 5
This is what I have tried:
int i = 0;
int j = 0;
while (i < dateTimes1.Length && j < dateTimes2.Length)
{
if (dateTimes1[i].Date == dateTimes2[j].Date && dateTimes1[i].Hour == dateTimes2[j].Hour)
{
list.Add(i);
list2.Add(j);
i++;
}
else if (dateTimes1[i] < dateTimes2[j])
{
i++;
}
else if (dateTimes1[i] > dateTimes2[j])
{
j++;
}
}
for (int k = 0; k < list.Count; k++)
{
Console.WriteLine(list[k] + " , " + list2[k];
}
but it won't output the index number after 1pm.
Upvotes: 7
Views: 5902
Reputation: 7369
Using Linq:
var hour = new TimeSpan(1, 0, 0);
var dt2MaxValue = dateTimes2.Max();
for (int i = 0; i < dateTimes1.Length; i++)
{
var output = string.Format("{0}, {1}",
i,
dateTimes2
.Select((o, index) => new { index = index, value = o })
.Where(dt2 => (dateTimes1[i] - dt2.value) < hour
|| dt2.value == dt2MaxValue)
.Select(dt2 => dt2.index)
.FirstOrDefault());
Console.WriteLine(output);
}
What the above Linq statement does:
The first Select
uses that method's overload which also passes the index of the item. This simply allows that info to cascade through. It uses an anonymous object with both index and the collection item being the index
and value
properties, respectively.
The Where
clause queries the collection of these anonymous objects and compares their value
with dateTime1[i]
. It gets the one where value
is less than dateTime1[i]
but not by more than 1 hour, OR if it is the maximum value
in the whole collection.
The second Select
simply gets the indexes of the items that Where
filtered through.
And FirstOrDefault
returns just that (ie, the first or default, which is the index of the item selected or 0 if no item was selected).
Upvotes: 0
Reputation: 1505
Here's a pretty basic method using Array.FindIndex
and foreach
:
EDIT: Updated this answer to handle the "matchup the last available index number of array2 for all of the datetime data from array1 that later than array2." issue.
foreach (DateTime dt in dateTimes1)
{
int currentHour = dt.Hour;
int lastHour = dateTimes2[dateTimes2.GetUpperBound(0)].Hour; //GetUpperBound(0) is the last index
int dt1index = Array.FindIndex(dateTimes1, a => a == dt); //get the index of the current item in dateTimes1
int dt2index = Array.FindIndex(dateTimes2, x => x.Hour == currentHour); //get the index of the item in dateTimes2 matching dateTimes1 hour field
if (currentHour > lastHour)
{
Console.WriteLine("{0}, {1}", dt1index, dateTimes2.GetUpperBound(0));
}
else
{
Console.WriteLine("{0}, {1}", dt1index, dt2index);
}
}
This simply looks at each of the values in dateTimes1
and dateTimes2
and returns the first match it finds (very similar to your loop).
To determine dt1index
, we look through dateTimes1
and return the first match where a => a == dt
(a is just the predicate, representing the "current" value in dateTimes1
- think of i = 0,1,2,etc
in a regular loop ).
Similarly, to determine dt2index
, we look for the first match on x => x.Hour == dt.Hour
-- that is, where the "current" dt
's hour field matches the hour field in dateTimes2
.
In both cases, the first match is returned - if no matches are found, -1
is returned.
When we go to write to the console, we check if currentHour
is greater than the last hour in dateTimes2
if so, we just write the current index of dateTimes1
and the last index of dateTimes2
. Otherwise, we write the current index of dateTimes1
and the index where the hour matches on dateTimes2
.
Upvotes: 0
Reputation: 19207
Your two lists are not the same length. In your while statement you are trying to iterate two different length lists at the same time.
If I understand your requirements properly you should be doing something like this by using an inner loop:
DateTime[] dateTimes1 = new DateTime[]
{
new DateTime(2010, 10, 1, 8, 15, 0),
new DateTime(2010, 10, 1, 8, 30, 1),
new DateTime(2010, 10, 1, 8, 45, 2),
new DateTime(2010, 10, 1, 9, 15, 3),
new DateTime(2010, 10, 1, 9, 30, 4),
new DateTime(2010, 10, 1, 9, 45, 5),
new DateTime(2010, 10, 1, 10, 15, 6),
new DateTime(2010, 10, 1, 10, 30, 7),
new DateTime(2010, 10, 1, 10, 45, 8),
new DateTime(2010, 10, 1, 11, 15, 9),
new DateTime(2010, 10, 1, 11, 30, 10),
new DateTime(2010, 10, 1, 11, 45, 11),
new DateTime(2010, 10, 1, 12, 15, 12),
new DateTime(2010, 10, 1, 12, 30, 13),
new DateTime(2010, 10, 1, 12, 45, 14),
new DateTime(2010, 10, 1, 13, 15, 15),
new DateTime(2010, 10, 1, 13, 30, 16),
new DateTime(2010, 10, 1, 13, 45, 17),
new DateTime(2010, 10, 1, 14, 15, 18),
new DateTime(2010, 10, 1, 14, 30, 19),
new DateTime(2010, 10, 1, 14, 45, 20),
};
DateTime[] dateTimes2 = new DateTime[]
{
new DateTime(2010, 10, 1, 8, 0, 0),
new DateTime(2010, 10, 1, 9, 0, 1),
new DateTime(2010, 10, 1, 10, 0, 2),
new DateTime(2010, 10, 1, 11, 0, 3),
new DateTime(2010, 10, 1, 12, 0, 4),
new DateTime(2010, 10, 1, 13, 0, 5),
};
int i = 0;
while (i < dateTimes1.Length)
{
int j = 0;
while (j < dateTimes2.Length))
{
if (dateTimes1[i].Date == dateTimes2[j].Date && dateTimes1[i].Hour == dateTimes2[j].Hour)
{
list.Add(i);
list2.Add(j);
i++;
}
else if (dateTimes1[i] < dateTimes2[j])
{
i++;
}
else if (dateTimes1[i] > dateTimes2[j])
{
j++;
}
}
}
for (int k = 0; k < list.Count; k++)
{
Console.WriteLine(list[k] + " , " + list2[k];
}
Upvotes: 2