简体   繁体   English

遍历2个嵌套列表

[英]Iterate over 2 nested lists

I am writing a weather app and need to go through 2 nested loops. 我正在编写一个天气应用程序,需要经历2个嵌套循环。 For the return value I want to iterate over the first list, looking at the corresponding second list data. 对于return值,我想遍历第一个列表,查看相应的第二个列表数据。 When the data in the second list matches the bool , I need to get data from the corresponding first list. 当第二个列表中的数据与bool匹配时,我需要从相应的第一个列表中获取数据。 Now I think that my code works... but would like to ask if this is a good way to do this. 现在,我认为我的代码可以工作...但是想问一下这是否是实现此目的的好方法。 I am also not sure if this LINQ query will work in general, with even more nested lists. 我也不确定这个LINQ查询是否可以正常工作,甚至可以使用更多的嵌套列表。 Here's my approach in 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;
}

Your code is OK, it is a LINQ query.But one more thing. 您的代码还可以,这是一个LINQ查询,但还有一件事。 Use FirstOrDefault() instead of First() . 使用FirstOrDefault()代替First() First() will throw an exception if no matched element is found, but FirstOrDefault() will return the element or the default value. 如果找不到匹配的元素,则First()将引发异常,但是FirstOrDefault()将返回该元素或默认值。

You can also write in LINQ Method syntax if you prefer this. 如果愿意,也可以用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;
}

I believe your query should work, and it should generally work with more nested lists following a similar structure. 我相信您的查询应该可以使用,并且通常应该使用类似结构的更多嵌套列表。 As to if it is a good way to do this - it depends on the data structure and any data constraints. 至于这是否是一个好方法-它取决于数据结构和任何数据约束。

For example, if two elements in weather.list have an element in their nested weather list might have the same id, then your code will only return the first one - which may not be correct. 例如,如果weather.list中的两个元素的嵌套weather列表中的元素可能具有相同的ID,那么您的代码将仅返回第一个元素-可能不正确。

eg in json: 例如在json中:

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

For this dataset, your code will return "Chicago", but "New York" also matches. 对于此数据集,您的代码将返回“芝加哥”,但“纽约”也将匹配。 This may not be possible with the data API you are accessing, but given that there are no data constraints to ensure exclusivity of the nested lists, you might want to defensively check that there is only 0 or 1 elements in the returned list that match the expected criteria. 对于正在访问的数据API,这可能无法实现,但是鉴于没有数据约束来确保嵌套列表的排他性,您可能需要防御性地检查返回的列表中只有0或1个元素与预期标准。

Another suggestion 另一个建议

On another note, not strictly an answer to your question - if you think your code will work but aren't sure, write a unit test. 另一方面,并​​不是严格地回答您的问题-如果您认为您的代码可以工作,但不确定,请编写单元测试。 In this case, you'd wrap the call to WeatherAPI in a class that implements an interface you define. 在这种情况下,您可以将对WeatherAPI的调用包装在实现您定义的接口的类中。 Update your method to call the method on a reference to the interface. 更新您的方法以在对接口的引用上调用该方法。

For your real application, ensure that an instance of the wrapper/proxy class is set on the reference. 对于您的实际应用程序,请确保在引用上设置了wrapper / proxy类的实例。

For the unit test, use a framework like Moq to create a mock implementation of the interface that returns a known set of data and use that instead. 对于单元测试,请使用Moq之类的框架来创建接口的模拟实现,该接口将返回已知数据集,并改用该数据集。 You can then define a suite of unit tests that use mocks that return different data structures and ensure your code works under all expected structures. 然后,您可以定义一组使用模拟的单元测试,这些模拟返回不同的数据结构,并确保您的代码在所有预期的结构下均可工作。

This will be a lot easier if your class is not a static method as well, and if you can use dependency injection ( Ninject , Autofac or one of many others...) to manage injecting the appropriate implementation of the service. 如果您的类也不是静态方法,并且可以使用依赖项注入( NinjectAutofac或许多其他方法之一)来管理注入服务的适当实现,则这将变得容易得多

Further explanations of unit testing, dependency injection and mocking will take more than I can write in this answer, but I recommend reading up on it - you'll never find yourself thinking "I think this code works" again! 单元测试,依赖注入和模拟的进一步说明将比我在此答案中所写的要花更多的钱,但是我建议您仔细阅读它-您将再也不会觉得“我认为这段代码有效”!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM