如何过滤二维数组

时间:2018-06-14 07:54:48

标签: ios arrays swift uitableview

我正在尝试使用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
}

2 个答案:

答案 0 :(得分:1)

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

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 /* ... */]

答案 1 :(得分:1)

我已修复了一些错误,并允许公开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(日期:&#34;星期一&#34;,weatherDetails:   [__lldb_expr_7.WeatherInfo(weatherImage:&#34; 10d&#34;,time:&#34; 12:00&#34;,   weatherType:&#34; Rain&#34 ;, temperature:&#34; 19.0&#34;),   __lldb_expr_7.WeatherInfo(weatherImage:&#34; 10d&#34;,time:&#34; 15:00&#34 ;, weatherType:&#34; Rain&#34 ;, temperature:&#34; 19.0&#34; )   __lldb_expr_7.WeatherInfo(weatherImage:&#34; 03n&#34;,time:&#34; 18:00&#34 ;, weatherType:&#34; Clouds&#34 ;, temperature:&#34; 16.0&#34; )]),   __lldb_expr_7.ForecastWeather(日期:&#34;星期四&#34;,weatherDetails:[__ lldb_expr_7.WeatherInfo(weatherImage:&#34; 01d&#34;,时间:&#34; 12:00&#34;,   weatherType:&#34; Clear&#34 ;, temperature:&#34; 35.0&#34;),   __lldb_expr_7.WeatherInfo(weatherImage:&#34; 02d&#34;,time:&#34; 15:00&#34 ;, weatherType:&#34; Clouds&#34 ;, temperature:&#34; 31.0&#34; )   __lldb_expr_7.WeatherInfo(weatherImage:&#34; 01n&#34;,time:&#34; 18:00&#34 ;, weatherType:&#34; Clear&#34 ;, temperature:&#34; 21.0&#34; )]),   __lldb_expr_7.ForecastWeather(日期:&#34;星期五&#34;,weatherDetails:[_ _ lldb_expr_7.WeatherInfo(weatherImage:&#34; 03n&#34;,time:&#34; 21:00&#34;,   weatherType:&#34;云&#34;,温度:&#34; 16.0&#34;),   __lldb_expr_7.WeatherInfo(weatherImage:&#34; 10n&#34;,time:&#34; 00:00&#34 ;, weatherType:&#34; Rain&#34 ;, temperature:&#34; 13.0&#34; )   __lldb_expr_7.WeatherInfo(weatherImage:&#34; 10d&#34;,time:&#34; 03:00&#34 ;, weatherType:&#34; Rain&#34 ;, temperature:&#34; 14.0&#34; )])]

修改

这是不正确的: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
    }