Есть ли способ очистить этот тип цикла с помощью LINQ?
List<Car> result;
List<string> makes;
List<string> models;
for (int i = 0; i < makes.Count() && i < models.Count(); i++)
{
result.Add(new Car() { Make = makes[i], Model = models[i] });
}
В основном я ищу способ сопоставить несколько массивов отдельных полей в один массив объектов, состоящих из этих полей.
В этом случае у меня его не было, но это немного поправило бы ситуацию. Тем не менее, мне нравится приведенный выше синтаксис, поскольку он позволяет вам не раскрывать поля в двух местах.





Вы можете использовать Enumerable.Range, например:
List<Car> result = Enumerable.Range(0, Math.Min(makes.Count, models.Count))
.Select(i => new Car { Make = makes[i], Model = models[i] }).ToList();
Если makes и models всегда содержат одинаковое количество элементов, вы можете использовать более компактный синтаксис:
List<Car> result = makes.Select((make, i) => new Car { Make = make, Model = models[i] }).ToList();
Это работает, но я надеялся, что будет что-то более синтаксически компактное.
Я обновил ответ, чтобы показать перегрузку Select (), которая допускает более компактный синтаксис.
Нужен ToList () для второго ответа. +1
В зависимости от того, как часто вам нужно будет писать запросы LINQ к этим массивам, может быть стоит создать класс, который обертывает массивы и реализует IEnumerable<Car>. Тогда ваш код выглядит так:
IEnumerable<Car> cars = new MyClass(makes, models);
var result = from cars...
Это не особенно сложно построить; это всего четыре простых метода (ну, шесть, если считать конструкторы), распределенных по двум классам (вам также необходимо реализовать IEnumerator<Car>).
Такой подход избавляет вас от необходимости встраивать детали реализации во все ваши запросы LINQ. Кроме того, если вы никогда этого не делали, этому действительно стоит научиться. Удобство внедрения IEnumerable<T> значительно расширяет пространство вещей, для которых вы можете легко использовать LINQ.
Похоже, вам действительно нужен новый оператор LINQ - тот, который не был включен в LINQ, несколько случайно: Zip. По сути, он принимает два перечислимых объекта и возвращает одно перечислимое число, которое объединяет парные записи, до тех пор, пока не завершится одна или другая из исходных последовательностей.
У меня нет ничего подобного в рукаве, но это не займет много времени, чтобы написать, если вам интересно. В результате код будет примерно таким:
List<Car> cars = makes.Zip(models)
.Select(pair => new Car(pair.First, pair.Second))
.ToList();
Дайте мне знать, если вам это интересно, и я запрограммирую это в MiscUtil.
На самом деле это было бы идеально, даже лучше, если бы он мог "заархивировать" более двух перечислимых элементов.
List<Car> result = makes
.Take(model.Count)
.Select((make, index) => new Car {Make = make, Model = models[index]});
Обратите внимание, что это работает, даже если марки и модели различаются по длине.
почему у вас нет конструктора для автомобиля с двумя параметрами ... марка и модель ...?