Как мне LINQify это?

Есть ли способ очистить этот тип цикла с помощью 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] });
  }

В основном я ищу способ сопоставить несколько массивов отдельных полей в один массив объектов, состоящих из этих полей.

почему у вас нет конструктора для автомобиля с двумя параметрами ... марка и модель ...?

Patrick Desjardins 08.10.2008 21:33

В этом случае у меня его не было, но это немного поправило бы ситуацию. Тем не менее, мне нравится приведенный выше синтаксис, поскольку он позволяет вам не раскрывать поля в двух местах.

Luke 08.10.2008 22:00
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
2
361
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Вы можете использовать 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();

Это работает, но я надеялся, что будет что-то более синтаксически компактное.

Luke 08.10.2008 21:32

Я обновил ответ, чтобы показать перегрузку Select (), которая допускает более компактный синтаксис.

Bradley Grainger 08.10.2008 21:37

Нужен ToList () для второго ответа. +1

Amy B 08.10.2008 21:46

В зависимости от того, как часто вам нужно будет писать запросы 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.

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

Luke 17.10.2008 02:05

List<Car> result = makes
                   .Take(model.Count)
                   .Select((make, index) => new Car {Make = make, Model = models[index]});

Обратите внимание, что это работает, даже если марки и модели различаются по длине.

Другие вопросы по теме