2011-08-10 11 views
0

날짜가 포함 된 AAA 목록을 날짜 범위와 비교하려고합니다. 목록에 날짜 범위가 있는지 확인하고 싶습니다. 날짜가있는 경우 목록 항목을 다른 목록에 복사합니다. BBB else BBB에 빈 값을 추가합니다.while 루프 난이도

내가 겪고있는 문제는 실제 코드에서는 while 루프의 거짓 진술을 어떻게 통과하지 못하는지 알지 못해서 비교가 끝날 때까지입니다.

아래 코드를 사용하면 while 루프에서 true와 false를 모두 전달하므로 필요한 결과가 위조됩니다. 내가 얻는 결과는 그것이있을 때마다이며, 나는 거짓과 같은 시간을 보내고 있습니다. 간단히 말해, 목록에 2010 년 6 월 5 일의 날짜가 포함되어 있고 날짜 범위는 2010 년 4 월 5 일에서 2010 년 7 월 5 일까지입니다. 그래서 나는 진실한 부분에서 창조 된 아이템을 갖게 될 것이며, 잘못된 부분에서 생성 된 아이템이 생길 것입니다. 존재하는 날짜는 참 또는 거짓 부분 일 수 있습니다. 두 가지 모두, 내가 빙과 같은 두 가지 아이템을 가지고 있습니다!

올바른 결과를 얻으려면 어떻게해야합니까? 다른 방법이나 suggetsion하시기 바랍니다. 다음과 같이

내 코드는 다음과 같습니다

DateTime StartDate; 
DateTime EndDate; 
Datetime tempDate = StartDate; 
List<DateTime> dateToEvaluate; 

bool TimeIsPresent = false; 
foreach (var tempItem in TaskList) 
{ 
    while (EndDate.AddDays(1) != tempDate) 
    { 
     if (tempItem.Date[0] == tempDate) 
     { 
      TimeIsPresent = True; 
      break; 
     } 
     else 
     { 
      if (TimeIsPresent == False) 
      { 
       if (!(tempDate.DayOfWeek == DayOfWeek.Sunday) 
       { 
        dateToEvaluate = new List<DateTime>(); 
        dateToEvaluate.Add(tempDate); 
        tempTask.Add(new GroupedTask { ID = null, 
                TaskID = null, 
                Date = dateToEvaluate }); 
       } 
      } 
     } 

     tempDate = tempDate.AddDays(1); 
        } 

    if (TimeIsPresent == True) 
    { 
     tempTask.Add(new GroupedTask { ID = tempItem.ID, 
             TaskID = tempItem.TaskID, 
             Date = tempItem.Date }); 
     TimeIsPresent = false; 
    } 
} 

나를 당신에게 예를 보자. 내 일정 범위는 다음과 같습니다 : 8 월 8 일 - 8 월 14 일 일요일 이제 내 작업 목록은 다음과 같습니다. item1 : Date 9Aug, item2 : Date 11Aug.

다음과 같이 그래서 내 tempTask이 있어야합니다 : 항목 1 : 날짜 8월 8일, TASKID : 널 (null), ID : 널 (null), 항목 2 : 날짜 8월 9일, TASKID : 678, ID : 7, 항목 3 : 날짜 10Aug, TASKID : null, ID : null, item4 : Date11 Aug, taskID : 890, ID : 34, item5 : date 8 월 8 일 taskID : null, ID : null, item6 : 8 월 13 일 taskID : null, ID : null


두 번째 예 :

다음과 같이 일 내 범위는 : 월 8월 8일 - 선드 다음과 같이 바깥 8월 14일 지금 내 작업 목록은 다음과 같습니다 항목 1 : 날짜 9Aug, 항목 2 : 날짜 11Aug, 항목 3 : 날짜 14Aug

다음과 같이 그래서 내 tempTask은 다음과 같아야합니다 항목 1 : 날짜 8월 8일, TASKID : 널 (null), ID : null, item2 : date 9 Aug, taskID : 678, ID : 7, item3 : 날짜 10Aug, taskID : null, ID : null, item4 : Date118, taskID : 890, ID : 34, item5 : 날짜 12 팔월, TASKID : 널 (null), ID : 널 (null), 는 item6 : 날짜 13 팔월, TASKID : 널 (null), ID : 널 (null), 는 item4는 : Date14 8월, TASKID : 894, ID : 74,

+2

왜 TimeIsPresent에 'bool'을 사용하지 않고 'false'로 설정해야합니까? –

+5

'TimeIsPresent'를'bool'로 정의하면'true'와'false'를 따옴표로 묶을 필요가 없습니다. 사실'if (TimeIsPresent)'또는'if (! TimeIsPresent)'대신에. – Gabe

+0

'EndDate'는 어디에서 왔으며 왜 'EndDate.AddDays (1)'를 다시 계산합니까? – R0MANARMY

답변

0

는 잘 모르겠어요 무엇을 은 입니다. 종료일, tempDate 및 다른 몇 가지 예입니다. 당신이 DATERANGE를 통해 루프를 시도하고 특정 날짜의 존재를 확인하는 경우에, 당신은 다음과 같은 예를 고려할 수 :

static void yourFunction() 
    { 
     // 
     //Some Stuffs 
     // 
     foreach (var tempItem in TaskList) 
     { 
      if (DateRange.Contains(tempItem.Date[0])) 
      { 
       //Do Task 
      } 
      else 
      { 
       //Do Task 
      } 
     } 
     // 
     //Some Stuffs 
     // 
    } 
    public static IEnumerable<DateTime> DateRange 
    { 
     get 
     { 
      for (DateTime day = startDate; day < EndDate; day = day.AddDays(1)) 
      { 
       yield return day; 
      } 
     } 
    } 

속성에 날짜 범위를 캡슐화하는 것은존 소총의 생각이다 , 나는 그의 책에서 그것을 배웠다 C# in Depth

+0

Date DateRange는 무한 루프에 들어갑니다 !!! – learning

+0

버그로 시간을 낭비해서 죄송합니다! 'DateTime'은 불변이므로 단순히'day.AddDays (1)'을 두는 것은 루프에 영향을 미치지 않습니다. 우리는 'day = day.AddDays (1)'와 같이 날짜를 증가시켜야합니다. 내 코드를 업데이트했습니다. – NaveenBhat

+0

감사합니다. 솔루션을 안내해주었습니다. 나를 도와 주려고하는 모든 분들께 감사드립니다 !! – learning

1

나는 당신이 정말로 그들이하는 것보다 어려운 것을 만들고있다라고 생각한다.내가 이해하는 한, 당신은 TaskList의 각 항목을 가져 와서 날짜가 특정 범위 내에 있는지 확인하고 있습니다. 그럴 경우 다른 목록에 추가하고 다음 항목으로 이동하십시오. 그렇지 않으면 빈 목록을 다른 목록에 추가하고 계속 확인합니다. 나의 이해가 맞으면

,이 시도 :

영업 이익의 의견에 따라 수정 됨

코드는 이제 TaskList 각 항목의 전체 범위를 통과하고, 함께 빈 개체 중 하나를 추가합니다 날짜 또는 날짜에 해당하는 작업.

이 시나리오에 날짜가 있는지 확인하려면 bool을 사용할 필요가 없습니다. EDITED

// Note that you'll have to assign values to StartDate and EndDate, otherwise you'll get 
// a Null Reference Exception 
DateTime StartDate; 
DateTime EndDate; 
Datetime tempDate = StartDate; 
List<DateTime> dateToEvaluate; 

foreach (var tempItem in TaskList) 
{ 
    // Reset tempDate to the starting date before each loop 
    tempDate = StartDate; 

    while (EndDate.AddDays(1) != tempDate) 
    { 
     if (tempDate.DayOfWeek != DayOfWeek.Sunday) 
     { 
      if (tempItem.Date[0] == tempDate) 
      { 
       tempTask.Add(new GroupedTask { ID = tempItem.ID, 
               TaskID = tempItem.TaskID, 
               Date = tempItem.Date }); 
      } 
      else 
      { 
       dateToEvaluate = new List<DateTime>(); 
       dateToEvaluate.Add(tempDate); 
       tempTask.Add(new GroupedTask { ID = null, 
               TaskID = null, 
               Date = dateToEvaluate }); 
      } 

     } 

     tempDate = tempDate.AddDays(1); 
    } 
} 

는 7/1는 7/14을 통과 월요일에 시작하는,

는 2 주간의 범위를 가정 추가 할 수 있습니다. 두 작업 - 날짜가 7/3 인 작업 1과 날짜가 7/12 인 작업 2를 가정합니다. 나는 tempTask에서 다음을 기대할 것입니다 :

26 개의 요소 (두 개의 작업 항목 각각에 대해 13 개의 날짜), 모든 요소는 두 개의 작업에 대해 하나씩을 제외하고 널 ID를가집니다.

실제로 반복 목록이없는 통합 목록을 원하십니까? 즉, 예를 들어 13 개의 요소가 있고 2는 null이 아닌 ID를 갖습니다. 두 개 이상의 작업이 같은 날짜 일 경우 어떻게됩니까?

나는 각 루프가 시작되기 전에 tempDate를 시작으로 재설정하지 않았기 때문에 하나의 오류를 발견했습니다. 새로운 이해를 바탕으로

편집

좋아, 당신은 주어진 범위 내의 모든 날짜가 두 번째 목록을 시도하고, 그리고 GroupedTask 객체는 해당 날짜에 대한 기존 GroupedTask 것 중 하나 때문에 일치하는 항목이없는 경우 해당 날짜의 경우 null GroupedTask입니다.

당신이 Enigmativity의 답변을 살펴 보길 권합니다. 좀 더 우아한 해결책 일 수 있습니다. (제가 자세히 보지 않았지만) 다른 접근 방법이 있습니다. 가장 큰 변화는 while 루프와 foreach 루프를 뒤집었기 때문입니다.

// Note that you'll have to assign values to StartDate and EndDate, otherwise you'll get 
// a Null Reference Exception 
DateTime StartDate; 
DateTime EndDate; 

// Declare an instance of GroupedTask for use in the while loop 
GroupedTask newTask; 

Datetime tempDate = StartDate; 

// Loop through the entire range of dates 
while (EndDate.AddDays(1) != tempDate) 
{ 

    // You included Sundays in your example, but had earlier indicated they 
    // weren't needed. If you do want Sundays, you can remove this outer if 
    // block 
    if (tempDate.DayOfWeek != DayOfWeek.Sunday) 
    { 

     // Create a "null" GroupedTask object 
     // The Date property in GroupedTask appears to be a List<DateTime>, 
     // so I chose to initialize it along with the other properties. 
     newTask = new GroupedTask() { ID = null, 
             TaskID = null, 
             Date = new List<DateTime>() { tempDate }}; 

     // For each date in the range, check to see if there are any tasks in the TaskList 
     foreach (var tempItem in TaskList) 
     { 
      // If the current item's date matches the current date in the range, 
      // update the newTask object with the current item's values. 
      // NOTE: If more than one item has the current date, the last one in 
      // will win as this code is written. 
      if (tempItem.Date[0] == tempDate) 
      { 
       newTask.ID = tempItem.ID; 
       newTask.TaskID = tempItem.TaskID; 
       newTask.Date = tempItem.Date; 
      } 
     } 

     // Add the newTask object to the second list 
     tempTask.Add(newTask); 
    } 
} 
+0

감사합니다. @Tim, 나는 당신이 내가 성취하고 싶은 것을 이해하지 못했다고 생각합니다. 코드를 사용하면 원하는 날짜가 아닌 범위에서 날짜를 찾을 때까지 목록을 반복합니다. 코드를 사용하면 목록의 범위에서 날짜를 찾으면 그 코드는 중지되고 그 이후의 모든 다른 날짜는 무시됩니다. 내가 원하는 것은 일요일을 제외하고 일요일과 목록 taskList가 tempTask 목록에있는 모든 날짜를 범위에 추가하는 것이며 목록에있는 값에 따라 값을 temptask에 복사합니다. 그것은 내 예제처럼 null 값을 복사합니다. – learning

+0

@learning - 내 편집 참조. 앞서 설명한 시나리오에서 날짜가 발견되면 부울을 참으로 설정할 필요가 없습니다. 간단히 각 날짜를 평가하고 해당 작업 항목 또는 null 작업 항목을 추가하십시오. – Tim

+0

@Tim에게 감사드립니다.이 코드는 문제를 해결하지 못합니다. 내가 2010 년 6 월 5 일 - 2010 년 7 월 5 일 - 화요일, 2010 년 8 월 5 일, 9/5/2010 - 내 takslist에 (예를 들어 가상의 날짜와 같은) 날짜가 있다고 가정 해 봅시다. 귀하의 코드는 tasklist에서 6/5/2010의 값만 읽으며 나머지는 null 값을가집니다. tempTask에 대한 코드 결과에는 예상 결과가 아닌 2010 년 6 월 5 일 값만 포함됩니다! tempTask에는 다른 모든 날짜가 포함되어 있지만 작업 목록 값은 포함되어 있지 않습니다! – learning

0

코드가 다소 혼란 스럽지만, 의도를 이해하면 LINQ를 사용하여 해결책을 찾을 수 있습니다. 내 접근 방식은 처음부터 다소 혼란 스러울 지 모르지만, 당신이 그것을 통해 일할 수있게 도와 드리겠습니다.

제 생각에 범위의 일치하는 날짜마다 기존 TaskList에서 개체를 가져올 GroupedTask 개체의 일치 목록을 만들거나, "더미 "인스턴스가 일치하지 않으면.

StartDate 변수를 질문에 사용 된 변수 EndDate과 함께 정의했다고 가정합니다.

내 솔루션 (I 시험이있는) 다음과 같습니다

var query = 
    from d in dates 
    from t in getTasksForDate(d) 
    where (t.ID != null) || (d.DayOfWeek != DayOfWeek.Sunday) 
    select t; 

tempTask.AddRange(query); 

필요로하는 두 부분으로 정의되는 순간 (dates & getTasksForDate) 쿼리가 각 날짜를 실행하여 작동에 대한 무시 끝까지 시작하여 해당 날짜의 작업 (TaskList 또는 날짜가없는 경우 "더미"작업)을 선택한 다음 일요일에 해당하는 "더미"작업을 필터링합니다. 그런 다음 작업이 tempTask 목록에 추가됩니다.

누락 된 부품이 있습니다.

는이 작업을 수행 dates 목록을 얻으려면 :

var days = EndDate.Date.Subtract(StartDate.Date).Days + 1; 

var dates = 
    Enumerable 
     .Range(1 - days, days) 
     .Select(d => EndDate.AddDays(d)); 

만큼 또는 EndDate 전에 당신이 지금 StartDate에 시작 EndDate에 종료 날짜 목록이있을 것이다에 StartDate이 때문이다.

getTasksForDate은 까다로운 부분입니다.

먼저 TaskList 목록을 날짜를 해당 날짜의 GroupedTask 개체 목록으로 바꾸는 조회 기능으로 전환해야합니다. LINQ로 그것은 쉽게 :

var lookup = TaskList.ToLookup(x => x.Date[0].Date, x => new GroupedTask() 
{ 
    ID = x.ID, 
    TaskID = x.TaskID, 
    Date = x.Date, 
}); 

다음 당신이 일을 더이 있다면 날짜 또는 하나의 "더미"GroupedTask 개체에 대한 조회에서 GroupedTask 목록 중 하나를 반환하지 않습니다 getTasksForDate 기능을 작성해야 날짜에 대한 작업.

Func<DateTime, IEnumerable<GroupedTask>> getTasksForDate = d => 
{ 
    return lookup[d].DefaultIfEmpty(new GroupedTask() 
    { 
     ID = null, 
     TaskID = null, 
     Date = new List<DateTime>() { d, }, 
    }); 
}; 

그게 전부입니다.

당신은 당신이이 코드를 사용할 수 있습니다 TaskList에서 실제 값을 기준으로 StartDate 및/또는 EndDate을 정의 할 경우에는이 것을 없도록

var StartDate = TaskList.Select(t => t.Date[0].Date).Min(); 
var EndDate = TaskList.Select(t => t.Date[0].Date).Max(); 

나는 DateTime 참조 대부분의 후 .Date을 사용했습니다를 시간 구성 요소를 날짜로 변환합니다.

더 자세한 설명을 원하시면 외쳐주십시오.

0

나는 당신이하려는 일을 이해한다면, 당신이 그렇게하는 방식을 바꿀 것입니다. 먼저, 하나 또는 모름과 관련된 작업이있는 범위의 모든 날짜를 찾아서 날짜를 알 수 있도록 사전에 넣습니다. 그런 다음 tempTask를 만듭니다. 다음과 같은 것 :

 DateTime StartDate; 
     DateTime EndDate; 
     DateTime tempDate = StartDate; 
     List<DateTime> dateToEvaluate; 
     Dictionary<DateTime, List<Task>> dateTaskDict = new Dictionary<DateTime, List<Task>>(); 

     bool TimeIsPresent = false; 
     foreach (Task tempItem in TaskList) 
     { 
      while (EndDate.AddDays(1) != tempDate) 
      { 
       if (tempItem.Date[0] == tempDate) 
       { 
        List<Task> tasksForDate; 
        if (!dateTaskDict.TryGetValue(tempDate, out tasksForDate)) 
        { 
         tasksForDate = new List<Task>(); 
         dateTaskDict[tempDate] = tasksForDate; 
        } 
        tasksForDate.Add(tempItem); 
        break; 
       } 
       tempDate = tempDate.AddDays(1); 
      } 
     } 
     tempDate = StartDate; 
     while (EndDate.AddDays(1) != tempDate) 
     { 
      List<Task> tasks; 
      if (dateTaskDict.TryGetValue(tempDate, out tasks)) 
      { 
       foreach (Task aTask in tasks) 
        tempTask.Add(new GroupedTask { ID = aTask.ID, 
               TaskID = aTask.TaskID, 
               Date = tempDate }); 
      } 
      else 
      { 
       if (tempDate.DayOfWeek != DayOfWeek.Sunday) 
       { 
        tempTask.Add(new GroupedTask { ID = null 
               TaskID = null, 
               Date = tempDate }); 
       } 
      } 
     }