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)
{
}
это будет использоваться для вещи, сделанной для каждого дат, в отличие от вещи, сделанной с каждым датой... Это будет немного иначе.