【问题标题】:How do I LINQify this?我该如何 LINQify 这个?
【发布时间】:2008-10-08 17:17:22
【问题描述】:

有没有办法使用 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] });
  }

基本上,我正在寻找某种方法将多个单个字段数组整理成由这些字段组成的单个对象数组。

【问题讨论】:

  • 为什么你没有带有 2 个参数的 Car 的构造函数... 品牌和型号...?
  • 在这种情况下我没有,但这会清理一些东西。我确实喜欢上面的语法,因为它允许您避免在两个地方公开字段。

标签: c# .net linq


【解决方案1】:

你可以使用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();

如果makesmodels 始终包含相同数量的项目,您可以使用更紧凑的语法:

List<Car> result = makes.Select((make, i) => new Car { Make = make, Model = models[i] }).ToList();

【讨论】:

  • 这行得通,但我希望有一些语法更紧凑的东西。
  • 我已经更新了答案以显示 Select() 的重载,它允许更紧凑的语法。
  • 第二个答案需要一个 ToList() 。 +1
【解决方案2】:

听起来您确实需要一个新的 LINQ 运算符 - 一个未包含在 LINQ 中的运算符,有点意外:Zip。它基本上需要两个可枚举并返回一个可枚举的配对条目,直到一个或另一个原始序列完成。

我没有类似的东西,但如果你有兴趣,写起来应该不会花太长时间。生成的代码将类似于:

List<Car> cars = makes.Zip(models)
                      .Select(pair => new Car(pair.First, pair.Second))
                      .ToList();

如果您对此感兴趣,请告诉我,我会将其编码到MiscUtil

【讨论】:

  • 实际上这将是完美的,如果它可以“压缩”而不是仅仅 2 个枚举,那就更好了。
【解决方案3】:

根据您需要对这些数组编写 LINQ 查询的频率,可能值得构建一个包装数组并实现 IEnumerable&lt;Car&gt; 的类。那么你的代码如下所示:

IEnumerable<Car> cars = new MyClass(makes, models);
var result = from cars...

构建它并不是特别复杂;它只是分布在两个类中的四个简单方法(好吧,六个,如果算上构造函数)(您还需要实现IEnumerator&lt;Car&gt;)。

这种方法使您不必在所有 LINQ 查询中嵌入实现细节。此外,如果您从未这样做过,这确实值得学习。轻松实现 IEnumerable&lt;T&gt; 会显着扩展您可以轻松使用 LINQ 的事物空间。

【讨论】:

    【解决方案4】:
    List<Car> result = makes
                       .Take(model.Count)
                       .Select((make, index) => new Car {Make = make, Model = models[index]});
    

    请注意,即使品牌和型号的长度不同,这仍然有效。

    【讨论】:

      猜你喜欢
      • 2016-07-29
      • 2010-09-20
      • 2016-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 2011-09-02
      相关资源
      最近更新 更多