我有一个日期范围为字符串的列表(例如'2019-05-01','2019-05-02','2019-05-05'...)和相同的数组包含布尔值的长度。
我需要对照布尔值区域中日期的对应值检查日期范围内的每一天,对于值为FALSE的任何一天,请从日期范围中删除日期并将其分为两个范围找不到值。
我一直在寻找适合这种模式的算法,但没有找到能在删除日期后拆分日期范围的算法。
List<Tuple<string, string>> ranges = new List<Tuple<string, string>>();
List<string> dt_range = new List<string>() { "2019-05-01", "2019-05-02", "2019-05-03", "2019-05-04", "2019-05-05", "2019-05-06" };
var valid = new bool[dt_range.Count];
valid[0] = true;
valid[1] = true;
valid[2] = false;
valid[3] = false;
valid[4] = true;
valid[5] = true;
for(var i = 0; i < dt_range; i++)
{
if(valid[i] == true)
{
// Continue checking days
}
else if (valid[i] == false)
{
// remove this day from date range, and create
// date range prior and following this, while
// continuing to check for the rest of the days
}
}
因此,如果在2019-05-03中该值为FALSE,则该范围将细分为(2019-05-01,2019-05-02)和(2019-05-04,2019-05-05) ,2019,05-06),并将继续检查第二个范围,如有需要,请分拆。第一个范围(2019-05-01,2019-05-02)将添加到范围列表>中,而第二个范围需要继续进行验证,然后才能添加到范围列表中。
我在解决此问题方面遇到了精神障碍,我们将不胜感激。
答案 0 :(得分:1)
如果我对要求的理解是正确的,那么下面的代码可以解决您的第一级问题。
List<string> dt_range = new List<string>() { "2019-05-01", "2019-05-02", "2019-05-03", "2019-05-04", "2019-05-05", "2019-05-06" };
var valid = new bool[dt_range.Count];
valid[0] = true;
valid[1] = true;
valid[2] = false;
valid[3] = false;
valid[4] = true;
valid[5] = true;
List<List<string>> FinalRange = new List<List<string>>();
for (var i = 0; i <= valid.Length-1; i++) {
List<string> Splitted_Date_Range = new List<string>();
if (!valid[i]) {
for (int j = 0; j <i; j++) {
Splitted_Date_Range.Add(dt_range[j]);
}
for (int j = i + 1; j <= valid.Length - 1; j++) {
Splitted_Date_Range.Add(dt_range[j]);
}
}
if (Splitted_Date_Range.Count > 0) {
FinalRange.Add(Splitted_Date_Range);
}
}
我编写的循环用于核心级别的实现示例,可用于进一步的日期拆分。
答案 1 :(得分:1)
我同意@juharr的观点,认为会有更好的数据结构来解决您的问题,我也强烈建议使用DateTime
存储日期,而不是string
。但是,使用您提供的示例,下面有一个解决方案。基本上,您在最后一个有效元素(我称为previous
)上保留一个标记,然后在遇到无效元素时对其进行更新。
List<Tuple<string, string>> ranges = new List<Tuple<string, string>>();
List<string> dt_range = new List<string>() { "2019-05-01", "2019-05-02", "2019-05-03", "2019-05-04", "2019-05-05", "2019-05-06" };
var valid = new bool[dt_range.Count];
valid[0] = true;
valid[1] = true;
valid[2] = false;
valid[3] = false;
valid[4] = true;
valid[5] = true;
string previous = dt_range.First();
for (int i = 0; i < dt_range.Count; i++) {
if (!valid[i]) {
if (previous != dt_range[i]) {
ranges.Add(new Tuple<string, string>(previous, dt_range[i - 1]));
}
previous = dt_range[i + 1];
}
}
// capture last range
ranges.Add(new Tuple<string, string>(previous, dt_range.Last()));
我从中获得的输出是两个范围,我相信它们与您想要的输出相匹配。
(2019-05-01,2019-05-02)
(2019-05-05,2019-05-06)
答案 2 :(得分:1)
将我的帽子扔进戒指,并假设您不需要空白范围,但想要任何余量,我认为它应该看起来像这样:
var ranges = new List<List<string>>();
var dt_range = new List<string> {"2019-05-01","2019-05-02","2019-05-03","2019-05-04","2019-05-05","2019-05-06"};
var validDates = new[] {true, true, false, false, true, true};
int i = 0;
int startPos = 0;
foreach (var valid in validDates)
{
if (!valid)
{
if ((i-startPos) > 0 )
ranges.Add(dt_range.Skip(startPos).Take(i - startPos).ToList());
startPos = i + 1;
}
i++;
}
// Handle any remaining dates
if (startPos < i)
ranges.Add(dt_range.Skip(startPos).Take(i - startPos).ToList());
答案 3 :(得分:1)
只有一个循环就可以了
List<Tuple<string, string>> ranges = new List<Tuple<string, string>>();
string str1 = null;
string str2 = null;
for (int i = 0; i < dt_range.Count; i++)
{
if (valid[i])
{
if (str1 == null)
{
str1 = dt_range[i];
}
str2 = dt_range[i];
}
else
{
if (str1 != null)
{
ranges.Add(Tuple.Create(str1, str2));
}
str1 = null;
}
}
if (str1 != null)
{
ranges.Add(Tuple.Create(str1, str2));
}
答案 4 :(得分:0)
我会用另一种方式解决这个问题,Linq:
var groupedRange = dtRange.GroupBy(g => valid[dtRange.IndexOf(g)] );
或者举一个完整的例子:
List<string> dtRange = new List<string>() {"2019-05-01","2019-05-02","2019-05-03","2019-05-04","2019-05-05","2019-05-06"};
var valid = new bool[dtRange.Count];
valid[0] = true;
valid[1] = true;
valid[2] = false;
valid[3] = false;
valid[4] = true;
valid[5] = true;
var groupedRange = dtRange.GroupBy(g => valid[dtRange.IndexOf(g)] );
foreach(var gr in groupedRange)
{
foreach(var row in gr)
{
Console.WriteLine(gr.Key + " " + row);
}
}
您最终得到一个包含两个列表的新对象。
输出为:
True 2019-05-01
True 2019-05-02
True 2019-05-05
True 2019-05-06
False 2019-05-03
False 2019-05-04