迭代2个嵌套列表

本文关键字:列表 嵌套 2个 迭代 | 更新日期: 2023-09-27 18:03:09

我正在编写一个天气应用程序,需要通过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个嵌套列表

您的代码是OK的,这是一个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;
}

我相信您的查询应该工作,并且它通常应该与遵循类似结构的嵌套列表一起工作。至于这是否是一种好方法,这取决于数据结构和任何数据约束。

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

。json:

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

对于这个数据集,您的代码将返回"Chicago",但"New York"也匹配。对于您正在访问的数据API来说,这可能是不可能的,但是考虑到没有数据约束来确保嵌套列表的排他性,您可能希望谨慎地检查返回的列表中只有0或1个元素符合预期的标准。

的另一个建议另一个注意事项,不是严格地回答你的问题-如果你认为你的代码将工作,但不确定,写一个单元测试。在这种情况下,您将把对WeatherAPI的调用包装在实现您定义的接口的类中。更新您的方法以调用对接口的引用的方法。

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

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

如果你的类也不是静态方法,并且你可以使用依赖注入(Ninject, Autofac或许多其他方法中的一个…)来管理注入适当的服务实现,这将容易得多。

关于单元测试、依赖注入和mock的进一步解释将超出我在这个回答中所能写的范围,但我建议你仔细阅读——你将再也不会发现自己在想"我认为这段代码可以工作"!