用范围内的值填充列表

时间:2019-10-25 07:15:20

标签: c# list linq

我有如下日期列表:

2017-02-08 00:00:00.000
2017-02-08 00:00:00.000
NULL
2017-03-20 00:00:00.000
NULL
2017-03-20 00:00:00.000
NULL
NULL
2017-03-20 00:00:00.000
2017-02-08 00:00:00.000
NULL
NULL
NULL
2017-02-08 00:00:00.000

应该这样填写。 也就是说,将具有相似邻居的所有日期最多填充2个NULL值。

2017-02-08 00:00:00.000
2017-02-08 00:00:00.000
NULL
2017-03-20 00:00:00.000
2017-03-20 00:00:00.000
2017-03-20 00:00:00.000
2017-03-20 00:00:00.000
2017-03-20 00:00:00.000
2017-03-20 00:00:00.000
2017-02-08 00:00:00.000
NULL
NULL
NULL
2017-02-08 00:00:00.000

这是我到目前为止构建的。任何想法表示赞赏

DateTime? latestDate = null;

foreach (var date in dates)
{
    if (date == null)
    {
        latestDate = date;
    }
    else
    {
        date = latestDate;
    }
}

3 个答案:

答案 0 :(得分:2)

为简化起见,不处理字符串分析和日期比较。
为了获得清晰的mreDateTime现在为int
Live demo

测试用例。

根据问题,我有以下测试用例:

//Input                           Expected Output
{ null, 1 },                    { null, 1 } 
{ null, null, 1 },              { null, null, 1 } 
{ null, null , null, 1 },       { null, null , null, 1 } 

{ 1, null, 1 },                 { 1, 1, 1 } 
{ 1, null, null, 1 },           { 1, 1, 1, 1 } 
{ 1, null, null, null, 1 },     { 1, null, null, null, 1 } 

{ 1, null, 2 },                 { 1, null, 2 } 
{ 1, null, null, 2 },           { 1, null, null, 2 } 
{ 1, null, null, null, 2 },     { 1, null, null, null, 2 } 

代码。

在这里,我们将不会查找代码优化,最小变量分配或保留我们刚刚读取的最后一个值。 我们会靠近测试用例。

for (int i = 0; i < input.Length - 1; i++)
{
    if (i == 0) { continue; } //First elment? Skip.
    if (input[i] != null) { continue; }// Already have a value? Skip.

    // First and last elment are safe.
    int? closestValueLeft = input[i - 1];
    int? closestValueRight = input[i + 1];

    // ####  CASE 1 #### : Left and right have value. 
    if (closestValueLeft != null && closestValueRight != null)
    {
        if (closestValueLeft == closestValueRight)
        {// both are the same. 
            input[i] = closestValueLeft;
        }
    }

    // ####  CASE 2 #### : Left and right don't have value. 
    else if (closestValueLeft == null && closestValueRight == null)
    {// Left and right have no value, Skip.
        continue;
    }

    // ####  CASE 3 #### : We have to move a bit to find 
    else
    {// Either left or right have a value but not both. We are gona move one step after the null. 
        if (closestValueLeft != null)
        { // Left is not null move right. 
            if (i + 2 < input.Length)// Array out of bound protection
            {
                closestValueRight = input[i + 2];
            }
        }
        else
        {// Right is not null, move left. 
            if (i - 2 > 0)// Array out of bound protection
            {
                closestValueLeft = input[i - 2];
            }
        }

        if (closestValueLeft == closestValueRight)
        {
            input[i] = closestValueLeft;
        }
    }
}

答案 1 :(得分:1)

如果我理解这个问题,这就是解决方案:

declarations:[
      ...components....
      MyComponent  // <- adding this GOT RID of the ISSUE
]

@拖放好主意

foreach (var date in dates.Select((date, index) => new { date, index }))
{
    if (date.index - 2 < 0) continue;

    if (dates[date.index - 2].HasValue && 
        dates[date.index - 2].Value == date.date && 
       !dates[date.index - 1].HasValue)
    {
        dates[date.index - 1] = date.date;
    }
    else if (dates[date.index - 3].HasValue &&
             dates[date.index - 3].Value == date.date &&
            !dates[date.index - 1].HasValue &&
            !dates[date.index - 2].HasValue)
    {
        dates[date.index - 1] = date.date;
        dates[date.index - 2] = date.date;
    }
}

答案 2 :(得分:1)

我还没有测试过它是否可以重新创建日期列表,但是它(或者很接近的东西)应该可以工作

if (dates.Count > 2)
{
      int i = 0;
      do
      {
          if (dates[i] != null && dates[i + 1] == null && dates[i + 2] == null && (i + 3 >= dates.Count || dates[i + 3] != null))
          {
              dates[i + 1] = dates[i];
              dates[i + 2] = dates[i];
              i += 3;
          }
          else i++;
      } while (i < dates.Count - 3);
  }

编辑: 我可能误解了原始要求(请参阅评论)。如果是这样,这可能更合适

        if (dates.Count > 2)
        {
            int i = 0;
            do
            {
                if (dates[i] != null && dates[i + 1] == null && dates[i + 2] == dates[i])
                {
                    dates[i + 1] = dates[i];
                    i += 2;
                }
                else if (dates[i] != null && dates[i + 1] == null && dates[i + 2] == null && (i+3<dates.Count && dates[i + 3] == dates[i]))
                {
                    dates[i + 1] = dates[i];
                    dates[i + 2] = dates[i];
                    i += 3;
                }
                else i++;
            } while (i < dates.Count - 3);
        }