迭代2个嵌套列表

时间:2016-08-20 08:02:24

标签: c# linq

我正在编写一个天气应用程序,需要经历2个嵌套循环。对于return值,我想迭代第一个列表,查看相应的第二个列表数据。当第二个列表中的数据与bool匹配时,我需要从相应的第一个列表中获取数据。现在我认为我的代码有效......但是想问一下这是否是一个很好的方法。我也不确定这个LINQ查询是否可以正常工作,甚至更多的嵌套列表。这是我在LINQ中的方法:

public static async Task<string> UpdateWeather(string lat, string lon)
{
    WeatherObject weather = await WeatherAPI.GetWeatherAsync(lat, lon);

    var first = (from l in weather.list
                from w in l.weather
                where w.id == 800
                select l.city.name).First();

    return first;
}

2 个答案:

答案 0 :(得分:2)

你的代码没问题,这是一个LINQ查询。还有一件事。使用FirstOrDefault()代替First()。如果未找到匹配的元素,First()将抛出异常,但FirstOrDefault()将返回元素或默认值。

如果您愿意,也可以写LINQ Method syntax

public static async Task<string> UpdateWeather(string lat, string lon)
{
    WeatherObject weather = await WeatherAPI.GetWeatherAsync(lat, lon);

    var first = weather.list.Where(l => l.weather.Any(w => w.id == 800))
                            .Select(l => l.city.name)
                            .FirstOrDefault();

    return first;
}

答案 1 :(得分:0)

我相信您的查询应该有效,并且通常应该使用类似结构后面的更多嵌套列表。至于它是否是一种好方法 - 它取决于数据结构和任何数据约束。

例如,如果weather.list中的两个元素的嵌套weather列表中的元素可能具有相同的ID,那么您的代码将只返回第一个 - 这可能不正确。 / p>

e.g。在json:

[
  {
    city : {
      name : "Chicago"
    },
    weather : [
      {
        id = 799
      },
      {
        id = 800
      }
    ]
  },
  {
    city : {
      name : "New York"
    },
    weather : [
      {
        id = 800
      },
      {
        id = 801
      }
    ]
  }
}

对于此数据集,您的代码将返回&#34;芝加哥&#34;,但&#34;纽约&#34;也匹配。对于您正在访问的数据API,这可能无法实现,但鉴于没有数据限制来确保嵌套列表的排他性,您可能希望防御性地检查返回列表中只有0或1个元素与预期标准。

另一个建议

另一方面,并​​非严格地回答您的问题 - 如果您认为您的代码将起作用但不确定,请编写单元测试。在这种情况下,您将在实现您定义的接口的类中包含对WeatherAPI的调用。更新方法以在对接口的引用上调用方法。

对于您的实际应用程序,请确保在引用上设置了包装器/代理类的实例。

对于单元测试,使用类似Moq的框架来创建接口的模拟实现,该实现返回一组已知数据并使用它。然后,您可以定义一组单元测试,这些单元测试使用返回不同数据结构的模拟并确保您的代码在所有预期结构下工作。

如果您的类不是静态方法,并且如果您可以使用依赖注入(NinjectAutofac或许多其他方法之一...)来管理这将更容易注入适当的服务实现。

单元测试,依赖注入和模拟的进一步解释将比我在这个答案中写的要多,但我建议你阅读它 - 你永远不会发现自己的想法&#34;我认为此代码有效&#34;再次!