有没有办法使用 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();
听起来你真的需要一个新的 LINQ 运算符 - 一个没有包含在 LINQ 中的运算符,有点意外:Zip。它基本上需要两个可枚举并返回一个配对条目的枚举,直到一个或另一个原始序列完成。
我没有这样的东西,但如果你有兴趣,写起来应该不会花太长时间。生成的代码如下所示:
List<Car> cars = makes.Zip(models)
.Select(pair => new Car(pair.First, pair.Second))
.ToList();
如果您对此感兴趣,请告诉我,我将在MiscUtil中对其进行编码。
根据您需要针对这些数组编写 LINQ 查询的频率,可能值得构建一个包装数组并实现IEnumerable<Car>
的类。 然后你的代码看起来像这样:
IEnumerable<Car> cars = new MyClass(makes, models);
var result = from cars...
构建它并不是特别复杂;它只是四个简单的方法(好吧,如果你算上构造函数,六个)分布在两个类中(你还需要实现IEnumerator<Car>
)。
此方法使您不必在所有 LINQ 查询中嵌入实现详细信息。 另外,如果你从来没有这样做过,这真的是值得学习的东西。 轻松实现 IEnumerable<T>
会显著扩展您可以轻松地使用 LINQ 的事物的空间。
List<Car> result = makes
.Take(model.Count)
.Select((make, index) => new Car {Make = make, Model = models[index]});
请注意,即使品牌和型号的长度不同,这也有效。