C# 日期时间数组
本文关键字:数组 时间 日期 | 更新日期: 2023-09-27 18:33:48
我有两个数组,array1 具有从上午 8 点到下午 2 点按分钟计算的日期时间数据,array2 具有从同一日期上午 8 点到下午 1 点按小时计算的日期时间数据。
我想输出两个具有相同 datetime.hour 的数组的索引号,并且它应该与 array2 中所有 Array1 中晚于 array2 的日期时间数据的最后一个可用索引号相匹配。
例如,如果我有两个这样的日期时间数组:
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),
};
它应该给我输出:
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
这是我尝试过的:
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];
}
但它不会在下午 1 点之后输出索引号。
您的两个列表的长度不同。在您的 while 语句中,您正在尝试同时迭代两个不同的长度列表。
如果我正确理解您的要求,您应该使用内部循环来执行以下操作:
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];
}
这是一个使用 Array.FindIndex
和 foreach
的非常基本的方法:
编辑:更新了此答案以处理">匹配 array2 中晚于 array2 的所有日期时间数据的 array2 的最后一个可用索引号"问题。
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);
}
}
这只会查看 dateTimes1
和 dateTimes2
中的每个值,并返回它找到的第一个匹配项(与您的循环非常相似(。
为了确定dt1index
,我们查看dateTimes1
并返回第一个匹配项,其中a => a == dt
(a只是谓词,表示dateTimes1
中的"当前"值 - 想想i = 0,1,2,etc
在常规循环中(。
类似地,为了确定dt2index
,我们寻找x => x.Hour == dt.Hour
上的第一个匹配项——也就是说,"当前"dt
的小时字段与dateTimes2
中的小时字段匹配。
在这两种情况下,都会返回第一个匹配项 - 如果未找到匹配项,则返回-1
。
当我们去写入控制台时,我们检查currentHour
是否大于dateTimes2
的最后一小时,如果是,我们只写入dateTimes1
的当前索引和dateTimes2
的最后一个索引。否则,我们写入 dateTimes1
的当前索引和小时匹配的索引 dateTimes2
.
使用 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);
}
上述 Linq 语句的作用:
第一个
Select
使用该方法的重载,该方法也传递项的索引。这仅允许该信息级联。它使用匿名对象,索引和集合项分别是index
和value
属性。Where
子句查询这些匿名对象的集合,并将其value
与dateTime1[i]
进行比较。它得到value
小于dateTime1[i]
但不超过 1 小时的那个,或者如果它是整个集合中的最大value
。第二个
Select
只是获取Where
筛选的项目的索引。FirstOrDefault
只返回该值(即,第一个或默认值,即所选项目的索引,如果未选择任何项目,则返回 0(。