2016-03-21 2 views
0

У меня есть массив DateTimes:Возврат следующего значения в массиве, если условие истинно

public DateTime GetNextGame() 
{ 
    DateTime[] dateTimes = new DateTime[] 
    { 
     new DateTime(2016, 4, 11, 7, 5, 0), 
     new DateTime(2016, 4, 12, 7, 5, 0), 
     new DateTime(2016, 4, 13, 7, 5, 0), 
     new DateTime(2016, 5, 30, 7, 5, 0), 
     new DateTime(2016, 5, 31, 7, 5, 0), 
     new DateTime(2016, 6, 1, 7, 5, 0), 
     new DateTime(2016, 6, 2, 7, 5, 0), 
     new DateTime(2016, 6, 14, 7, 5, 0), 
     new DateTime(2016, 6, 15, 7, 5, 0), 
     new DateTime(2016, 6, 16, 7, 5, 0), 
     new DateTime(2016, 8, 16, 7, 5, 0), 
     new DateTime(2016, 8, 17, 7, 5, 0), 
     new DateTime(2016, 9, 12, 7, 5, 0), 
     new DateTime(2016, 9, 13, 7, 5, 0), 
     new DateTime(2016, 9, 14, 7, 5, 0), 
     new DateTime(2016, 9, 19, 7, 5, 0), 
     new DateTime(2016, 9, 20, 7, 5, 0), 
     new DateTime(2016, 9, 21, 7, 5, 0), 
     new DateTime(2016, 9, 22, 7, 5, 0) 
    }; 

Мой вопрос заключается в .., как я вернуть следующее значение в массиве, если текущее значение не соответствует состояние? Я сделал некоторые исследования по этому вопросу и нашел аналогичный вопрос, но это было в PHP, который я не понимал.

поэтому у меня есть цикл прохождения через массив, то условный оператор:

foreach(DateTime date in dateTimes) 
{ 
    if(date.TimeOfDay < DateTime.Today.TimeOfDay) 
    { 
     return //next value in array? 
    } 
} 

также пытается вернуть дату .ToShortDateString вместе с .ToShortTimeString на мой взгляд.

Я хочу, чтобы это выглядело, как это .. «Следующая Игра Понедельник, 3 марта в 7:05 вечера»

Любая помощь приветствуется.

+2

Вы можете использовать 'for' вместо' foreach'. 'for (int i = 0; i Valentin

+0

вы можете сохранить 'counter' для получения следующего значения, но почему вы не используете' for'? – SeM

+0

Для такого рода проблем, вероятно, просто проще использовать обычный цикл и вручную индексировать в массив. Затем просто используйте 'index + 1' (и выполните правильную обработку исключений). – ryanyuyu

ответ

1

You следует использовать for -loop, если вам нужно получить доступ к следующему (o г предыдущий) пункт:

for(int i = 0; i < dateTimes.Length - 1; i++) 
{ 
    (dateTimes[i].TimeOfDay < DateTime.Today.TimeOfDay) 
    { 
     return dateTimes[i + 1]; 
    } 
} 

Кроме того, ваше сравнение не имеет смысла:

if(date.TimeOfDay < DateTime.Today.TimeOfDay) 
{ 
    // this will never be true 
} 

DateTime.TimeOfDay возвращает TimeSpan в виде DateTime, поэтому компонент времени. DateTime.Today возвращает сегодняшнюю полночь, так что это TimeOfDay будет TimeSpan.Zero. Вот почему date.TimeOfDay < DateTime.Today.TimeOfDay никогда не будет правдой.

Я предполагаю, что вы хотите, чтобы первый DateTime, который был до сегодняшнего дня.Затем используйте:

if(date.Date < DateTime.Today) 
{ 
    // ... 
} 
1

Используйте for-loop вместо foreach.

for(int i = 0; i < dateTimes.Length; i++) 
{ 
    if(dateTimes[i].TimeOfDay < DateTime.Today.TimeOfDay && i < dateTimes.Length - 1) 
    { 
     return dateTimes[i + 1]; 
    } 
} 

отметить также нужна Там вы можете проверить, что you're не из границ массива путем записи if(i < dateTimes.Length).

Вы также можете комбинировать Петля-условия немного:

for(int i = 0; i < dateTimes.Length - 1; i++) 
{ 
    if(dateTimes[i].TimeOfDay < DateTime.Today.TimeOfDay) 
    { 
     return dateTimes[i + 1]; 
    } 
} 
+0

Вы можете поместить это ограничение 'i Valentin

1

Вы могли бы сделать просто

return dateTimes.OrderBy(dateTime => dateTime).FirstOrDefault(dateTime => dateTime > DateTime.Now); 

Или, если вы хотите использовать Today и TimeOfDay

return dateTimes.OrderBy(dateTime => dateTime).FirstOrDefault(dateTime => dateTime.Date > DateTime.Today && dateTime.TimeOfDay > DateTime.Today.TimeOfDay); 
+0

Короткие рабочие ответы. Но OP не хотел 'DateTime.Now', но' DateTime.Today.TimeOfDay'. – HimBromBeere

+0

@HimBromBeere Я добавил альтернативную версию – Szeki

1

Попробуйте for петлю вместо foreach:

for (int i = 0; i < dateTimes.Length; ++i) { 
    DateTime date = dateTimes[i]; 

    if (date.TimeOfDay < DateTime.Today.TimeOfDay) { 
    if (i < dateTimes.Length - 1) // not the last item 
     return date[i + 1]; 
    else { 
     //TODO: there's no "next item" for the last one 
    } 
    } 
} 
1

Если вы, по каким-то причинам не хотите использовать for цикл, то попробуйте это:

int counter = 0; 
foreach(DateTime date in dateTimes) 
{ 
    if(date.TimeOfDay < DateTime.Today.TimeOfDay) 
    { 
     return dateTimes[counter + 1]; 
    } 
    counter++; 
} 
+0

, это просто запутанный цикл 'for' - у вас есть инициализатор, условие и итератор.Как это не цикл for? :) – Default

+0

Я знаю, спасибо за совет. – SeM

2

Оператор Linq SkipWhile может использоваться:

  DateTime firstValid = dateTimes.SkipWhile(d => d.TimeOfDay < DateTime.Today.TimeOfDay).First(); 

EDIT: Просто хотел упомянуть, что мы предполагаем, что массив уже упорядочен по возрастанию.

+0

или добавить предложение 'OrderBy'. – Default

+0

Ну, я не знал, могут ли данные быть изменены, поэтому я дал понять, что мы предоставили ответы на основе исходных данных. –

+0

ну, конечно, я понимаю, почему вы добавили его :) Но если данные * * неупорядочены, можно было бы добавить 'OrderBy', чтобы отсортировать его. Я полагал, что это будет в значительной степени равным объемом текста, и он предоставит больше информации, а не просто откажется от этой проблемы. – Default

1

Вы можете попробовать:

foreach(DateTime date in dateTimes) 
{ 
    if(!(date.TimeOfDay < DateTime.Today.TimeOfDay)) 
    { 
     continue; 
    } 
    return date; 
} 
1

Когда вы заранее знаете, ваш массив полностью отсортирован, использование:

var idx = Array.BinarySearch(dateTimes, DateTime.Now); 

return dateTimes[idx >= 0 ? idx : ~idx]; 

Как и многие другие решения здесь, это не получится плохо, если нет предстоящих "Следующая игра". Убедитесь, что вы находитесь в пределах массива, если это нужно обработать более изящно.

Смежные вопросы