Linq, чтобы установить все значения массива в заданное значение

У меня есть немного кода, который я бы хотел включить в выражение linq (желательно с lambdas), чтобы упростить его использование в качестве делегата. Код выглядит следующим образом:

List<DateTime[]> changes = new List<DateTime[]>();
changes = PopulateChanges();
for (int i = 0; i < changes.Count; i++)
{
    for(int j = 0; j < changes[i].Length; j++)
    {
        changes[i][j] = DateTime.MinValue;
    }
}

В моей жизни я не могу понять этого. Я пробовал использовать ForEach и различные формы select и т.д. Кажется, что ничего не работает.

FYI, я знаю, что DateTime по умолчанию имеет значение MinValue, на самом деле это очищает массивы по умолчанию после того, как они уже установлены.

Может ли кто-нибудь помочь мне с рабочим выражением?

EDIT:

Я предполагаю, что я на самом деле говорю здесь, я хочу, чтобы сжатый способ установить все элементы многомерного массива на заданное значение. Разумеется, работает цикл вложенных циклов, и я могу, конечно, поместить его в функцию (которую я уже сделал). Я просто хочу нечто более сжатое, которое можно использовать более легко в делегате без создания многострочного монстра.

Ответ 1

Это должно сделать трюк.

Это не LINQ, и это не очень сильно отличается от ваших вложенных циклов for, немного немного подробных.

changes.ForEach(x => Array.Clear(x, 0, x.Length));

Есть определенные способы (ab) использовать LINQ для достижения тех же результатов, но я считаю, что они грязные хаки. Кроме того, эквивалент LINQ, вероятно, не будет менее подробным, чем мой пример выше.

Ответ 2

LINQ на самом деле не предназначен для обновления коллекций. Это о запросе, т.е. Создавать перечисления по существующим коллекциям. Я думаю, что ваш код отлично читается и не будет сильно улучшаться, если вы заставите его иметь много лямбда и т.д.

Если вы хотите создать новый List<DateTime[]> с каждым элементом, установленным в значение, вы можете сделать это:

var changes = Enumerable.Range(0, width)
                        .Select(x => Enumerable.Range(0, height)
                                               .Select(y => DateTime.MinValue)
                                               .ToArray())
                        .ToList();

Если вы действительно хотите это сделать, используя ForEach/LINQ, можно злоупотреблять Select (но я не рекомендую):

changes.ForEach(array => array.Select((dt, i) => array[i] = DateTime.Now)
                              .LastOrDefault());

Ответ 3

Интересный вопрос, но Linq о запросе и то, что вы здесь делаете, не очень похоже на запрос. Даже если есть решение, я не уверен, что использовал Linq для чего-то вроде этого.

Ответ 4

Можете ли вы описать некоторые варианты использования того, как вы предлагаете использовать указанный делегат?

Я имею в виду, если PopulateChanges() возвращает вам массивы List < > of DateTime, и вы просматриваете все их и устанавливаете их в DateTime.MinValue, что именно представляет собой блок кода, который вы хотите поместить в делегировать?

Ответ 5

Есть всегда лучшие практики и такие, но я не знаю, согласен ли я со всем, что все говорили...

Если вы правильно поняли, вы должны перечислить свой вложенный массив по нескольким причинам и хотите инкапсулировать эту функциональность, которая будет использоваться повторно. Существует несколько различных способов выполнения, но здесь вы используете linq и один из них..

List<DateTime[]> changes = new List<DateTime[]>();
changes = PopulateChanges();

// *** As pointed out ForEach this will not change the value in the array, Thanks!***
changes.ForEach(change => change.ToList().ForEach(date => date = DateTime.MinValue));

// this how ever works but is kind of confusing...
changes = changes.Select(change => change.Select(date => DateTime.MinValue).ToArray()).ToList();
//Even that would get old writing it over and over again...

Я бы сделал это так...

private void ForEachOnNestedDates(List<DateTime[]> list, Func<DateTime, DateTime> method)
{
   // Use your code...
   for (int i = 0; i < list.Count; i++)
   {
      for(int j = 0; j < list[i].Length; j++)
      {
          list[i][j] = method.Invoke(list[i][j]);
      }
   }
}

это позволит вам повторно использовать это и делать разные вещи для каждого элемента. напр.

//Add a Day to each datetime value
ForEachOnNestedDates(changes, (DateTime date) => date.AddDays(1));

//You also make it even more readable
ForEachOnNextedDates(changes, DoSomethingWithDate);

private DateTime DoSomethingWithDate(DateTime value)
{

}

это будет использоваться для вещи, сделанной для каждого дат, в отличие от вещи, сделанной с каждым датой... Это будет немного иначе.