【问题标题】:How to filter two dimensional array如何过滤二维数组
【发布时间】:2018-06-14 07:54:48
【问题描述】:

我正在尝试使用 Open Weather API 构建一个天气预报应用程序,并且在我的预测类中,我有以下结构类型。

struct ForecastWeather {
    public private(set) var date: String    
    public private(set) var weatherDetails: [WeatherInfo]
}

struct WeatherInfo {
    public private(set) var weatherImage: String
    public private(set) var time: String
    public private(set) var weatherType: String
    public private(set) var temperature: String
}

我需要使用二维数组,因为在我的表格视图中有预测数据的部分。我将对象放入var forecastWeathers = [ForecastWeather]() 数组中。

ForecastWeather(date: "Thursday", weatherDetails: [WeatherForecast.WeatherInfo(weatherImage: "01d", time: "12:00", weatherType: "Clear", temperature: "35.0")])
ForecastWeather(date: "Thursday", weatherDetails: [WeatherForecast.WeatherInfo(weatherImage: "02d", time: "15:00", weatherType: "Clouds", temperature: "31.0")])
ForecastWeather(date: "Thursday", weatherDetails: [WeatherForecast.WeatherInfo(weatherImage: "01n", time: "18:00", weatherType: "Clear", temperature: "21.0")])
ForecastWeather(date: "Friday", weatherDetails: [WeatherForecast.WeatherInfo(weatherImage: "03n", time: "21:00", weatherType: "Clouds", temperature: "16.0")])
ForecastWeather(date: "Friday", weatherDetails: [WeatherForecast.WeatherInfo(weatherImage: "10n", time: "00:00", weatherType: "Rain", temperature: "13.0")])
ForecastWeather(date: "Friday", weatherDetails: [WeatherForecast.WeatherInfo(weatherImage: "10d", time: "03:00", weatherType: "Rain", temperature: "14.0")])
ForecastWeather(date: "Monday", weatherDetails: [WeatherForecast.WeatherInfo(weatherImage: "10d", time: "12:00", weatherType: "Rain", temperature: "19.0")])
ForecastWeather(date: "Monday", weatherDetails: [WeatherForecast.WeatherInfo(weatherImage: "10d", time: "15:00", weatherType: "Rain", temperature: "19.0")])
ForecastWeather(date: "Monday", weatherDetails: [WeatherForecast.WeatherInfo(weatherImage: "03n", time: "18:00", weatherType: "Clouds", temperature: "16.0")])

在我的表格视图中,我需要像WeatherService.instance.forecastWeathers[indexPath.section].weatherDetails[indexPath.row] 一样将这些部分放入其中。它现在给了我一个错误,因为我里面有 3 个相同的星期四对象。如何映射或过滤仅包含一次日期信息的 forecastWeathers 数组,因为我有多个部分我尝试使用映射功能但我无法成功。

在这里编辑是我的 API 调用

        let json = JSON(value)

        for i in 0..<json["list"].count {
            let icon = json["list"][i]["weather"][0]["icon"].stringValue    // Image icon
            let  date = self.convertUnixDate(fromDoubleTo: json["list"][i]["dt"].doubleValue)
            let weatherType = json["list"][i]["weather"][0]["main"].stringValue.capitalized
            let temperature = "\(self.temperatureConverter(kelvinTo: json["list"][i]["main"]["temp"].doubleValue))"
            let time = self.convertTime(timeArr: json["list"][i]["dt_txt"].stringValue)

            let forecastObj = ForecastWeather(date: date, weatherDetails: [WeatherInfo(weatherImage: icon, time: time, weatherType: weatherType, temperature: temperature)])
            print(forecastObj)
            self.forecastWeathers.append(forecastObj)
        }

还有API结果5 day forecast

这是我的表格视图委托方法

func numberOfSections(in tableView: UITableView) -> Int {
    return WeatherService.instance.newForecastWeathers.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return WeatherService.instance.newForecastWeathers[section].date.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = forecastTableView.dequeueReusableCell(withIdentifier: cellId) as? ForecastCell else { return ForecastCell() }   
    cell.configureCell(weatherDetails: WeatherService.instance.newForecastWeathers[indexPath.section].weatherDetails[indexPath.row])
    return cell
}
 func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let view = UIView()
    view.backgroundColor = .orange
    let label = UILabel()
    label.text = WeatherService.instance.newForecastWeathers[section].date
    label.frame = CGRect(x: 45, y: 5, width: 100, height: 35)
    view.addSubview(label)
    return view
}

【问题讨论】:

  • 看我的回答
  • 我已经更新了答案

标签: ios arrays swift uitableview


【解决方案1】:

问题是您没有使用内部weatherDetails 作为数组,因为您总是只添加一个元素。 因此,您必须将属于同一天的 WeatherInfos 添加到该数组中,可能是这样:

struct ForecastWeather {
    public private(set) var date: String    
    public private(set) var weatherDetails = [WeatherInfo]()
    public init (date:String) {
      self.date = date
    }
    public mutating func addInfo(_ info:WeatherInfo) {
        weatherDetails.append(info)
    }
}

struct WeatherInfo {
    public private(set) var weatherImage: String
    public private(set) var time: String
    public private(set) var weatherType: String
    public private(set) var temperature: String
}

var thursday = ForecastWeather(date: "Thursday")
thursday.addInfo(WeatherInfo(weatherImage: "01d", time: "12:00", weatherType: "Clear", temperature: "35.0"))
thursday.addInfo(WeatherInfo(weatherImage: "02d", time: "15:00", weatherType: "Clouds", temperature: "31.0"))

var friday = ForecastWeather(date: "Friday")
friday.addInfo(WeatherInfo(weatherImage: "03n", time: "21:00", weatherType: "Clouds", temperature: "16.0"))
// ...

let forecastWeathers = [thursday, friday /* ... */]

【讨论】:

  • 我想他想对已经创建好的数组使用函数式编程
  • 感谢您的回答,但对于天气预报,我不知道接下来的 5 天会是什么,所以我无法添加像星期四、星期五这样的对象。 API 中有一些时间戳,我正在将其转换为日期名称。
  • @Vyacheslav 我不确定。我认为这在某种程度上取决于如何获取数据。内部数组的使用无论如何都不正确。
  • @AndreasOetjen 你真的不知道完整的应用程序逻辑可以肯定:)
  • @AtalayAsa 问题是您的成员weatherDetailsWeatherInfo 的数组,但您不将其用作数组,因为您只将一个WeatherInfo 实例存储到那个数组。因此,要么您必须将多个实例存储到该数组中,所有实例都属于同一天,要么根本没有数组。我想你想要第一个,而不是后者。我也认为你应该使用字典,正如 Vyacheslav 所发布的那样。
【解决方案2】:

我已经修复了一些错误并允许 weatherDetails 公开以简化附加。这是一种功能风格。带排序。

//: Playground - noun: a place where people can play

struct ForecastWeather {
    public private(set) var date: String
    public var weatherDetails: [WeatherInfo]

    public var index: Int {
        return ForecastWeather.weekdays[date] ?? 0
    }

    private static let weekdays: [String: Int] = ["Sunday": 0, "Monday": 1, "Thuesday": 2, "Wednesday": 3, "Thursday": 4, "Friday": 5, "Saturday": 6]
}

struct WeatherInfo {
    public private(set) var weatherImage: String
    public private(set) var time: String
    public private(set) var weatherType: String
    public private(set) var temperature: String
}

var forecastWeathers = [ForecastWeather]()
forecastWeathers.append(ForecastWeather(date: "Thursday", weatherDetails: [WeatherInfo(weatherImage: "01d", time: "12:00", weatherType: "Clear", temperature: "35.0")]))
forecastWeathers.append(ForecastWeather(date: "Thursday", weatherDetails: [WeatherInfo(weatherImage: "02d", time: "15:00", weatherType: "Clouds", temperature: "31.0")]))
forecastWeathers.append(ForecastWeather(date: "Thursday", weatherDetails: [WeatherInfo(weatherImage: "01n", time: "18:00", weatherType: "Clear", temperature: "21.0")]))
forecastWeathers.append(ForecastWeather(date: "Friday", weatherDetails: [WeatherInfo(weatherImage: "03n", time: "21:00", weatherType: "Clouds", temperature: "16.0")]))
forecastWeathers.append(ForecastWeather(date: "Friday", weatherDetails: [WeatherInfo(weatherImage: "10n", time: "00:00", weatherType: "Rain", temperature: "13.0")]))
forecastWeathers.append(ForecastWeather(date: "Friday", weatherDetails: [WeatherInfo(weatherImage: "10d", time: "03:00", weatherType: "Rain", temperature: "14.0")]))
forecastWeathers.append(ForecastWeather(date: "Monday", weatherDetails: [WeatherInfo(weatherImage: "10d", time: "12:00", weatherType: "Rain", temperature: "19.0")]))
forecastWeathers.append(ForecastWeather(date: "Monday", weatherDetails: [WeatherInfo(weatherImage: "10d", time: "15:00", weatherType: "Rain", temperature: "19.0")]))
forecastWeathers.append(ForecastWeather(date: "Monday", weatherDetails: [WeatherInfo(weatherImage: "03n", time: "18:00", weatherType: "Clouds", temperature: "16.0")]))

var storedForecastWeatherIndicies: [String: ForecastWeather] = [:]

forecastWeathers.forEach { value in
    guard storedForecastWeatherIndicies[value.date] == nil else {
        // if is already found
        storedForecastWeatherIndicies[value.date]?
            .weatherDetails
            .append(contentsOf: value.weatherDetails)
        return
    }
    // if a new value for the Dictinary
    storedForecastWeatherIndicies[value.date] = value
}

let result = storedForecastWeatherIndicies.values.map { $0 }.sorted { first, second in first.index < second.index }

print(result)

[__lldb_expr_7.ForecastWeather(日期:“星期一”,weatherDetails: [__lldb_expr_7.WeatherInfo(weatherImage:“10d”,时间:“12:00”, 天气类型:“雨”,温度:“19.0”), __lldb_expr_7.WeatherInfo(weatherImage:“10d”,时间:“15:00”,weatherType:“Rain”,温度:“19.0”), __lldb_expr_7.WeatherInfo(weatherImage:“03n”,时间:“18:00”,weatherType:“云”,温度:“16.0”)]), __lldb_expr_7.ForecastWeather(日期:“星期四”,weatherDetails:[__lldb_expr_7.WeatherInfo(weatherImage:“01d”,时间:“12:00”, 天气类型:“晴天”,温度:“35.0”), __lldb_expr_7.WeatherInfo(weatherImage:“02d”,时间:“15:00”,weatherType:“云”,温度:“31.0”), __lldb_expr_7.WeatherInfo(weatherImage: "01n", time: "18:00", weatherType: "Clear", temperature: "21.0")]), __lldb_expr_7.ForecastWeather(日期:“星期五”,weatherDetails:[__lldb_expr_7.WeatherInfo(weatherImage:“03n”,时间:“21:00”, 天气类型:“云”,温度:“16.0”), __lldb_expr_7.WeatherInfo(weatherImage:“10n”,时间:“00:00”,weatherType:“Rain”,温度:“13.0”), __lldb_expr_7.WeatherInfo(weatherImage: "10d", time: "03:00", weatherType: "Rain", temperature: "14.0")])]

编辑

这是不正确的:date.count 是您的字符串的长度。不是数组

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return WeatherService.instance.newForecastWeathers[section].date.count
}

改用weatherDetails

   func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return WeatherService.instance.newForecastWeathers[section].weatherDetails.count
    }

【讨论】:

  • 感谢您提供详细信息,但是当我在表格视图中使用时,它给我的错误索引超出范围 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell { guard let cell = forecastTableView.dequeueReusableCell(withIdentifier: cellId) as? ForecastCell else { return ForecastCell() } cell.configureCell(weatherDetails: WeatherService.instance.newForecastWeathers[indexPath.section].weatherDetails[indexPath.row]) return cell } btw newForecastWeathers 是您创建的一个数组。
  • @AtalayAsa 发布您的完整表格视图代表
  • 我认为问题在于“节数”和“节中的行数”
猜你喜欢
  • 1970-01-01
  • 2013-06-23
  • 2015-02-11
  • 2011-05-24
  • 2018-12-28
  • 2019-09-24
  • 2017-01-26
  • 2015-09-23
相关资源
最近更新 更多