简体   繁体   中英

Appending an item to an array is overriding the previous items and add a new one

I am having an issue appending items to an array. I am using Alamofire and the Open Weather API to get these items.

Getting the JSON response and parsing its not a problem. Adding the first item to the array also works fine.

Example of the items :

Date : Monday
High Temp : 85F
Low Temp : 72F
Weather Type : Rain

Date : Tuesday
High Temp : 102F
Low Temp : 97F
Weather Type : Sunny

Date : Wednesday
High Temp : 98F
Low Temp : 62F
Weather Type : Rain

Date : Thursday
High Temp : 95F
Low Temp : 92F
Weather Type : Cloudy

Date : Friday
High Temp : 83F
Low Temp : 77F
Weather Type : Sunny

Date : Saturday
High Temp : 100F
Low Temp : 85F
Weather Type : Sunny

These are store in a WeatherForecast object which in turn are added/appended to the WeatherForecasts array.

The problem is that what ends up happening is the last value being in this case Saturday ends up filling all six elements in the array.

Using a for loop I notice it went like this.

Added first item correctly, then add the second items twice overriding the first item. Then the third item overrides the first and the second items ... repeat until end.

What happens using numbers : 1 22 333 4444 55555 666666 <- final result, last element is repeat it 6 times.

What I want : 123456

My code follows :

class WeatherService
{
    private var weatherForecasts: [WeatherForecast] = [WeatherForecast]();
    private var weatherForecast: WeatherForecast = WeatherForecast();
    private var arrayOfInts: [Int] = [Int]();
    private var counter: Int = 0;

    public func downloadWeatherForecast(getForecastURL: String,
                completed: @escaping(_ weatherPayload: WeatherPayload) -> Void)
    {
        Alamofire.request(getForecastURL)
                 .responseJSON
        {
            response in

            let result = response.result;

            if let dict = result.value as? Dictionary<String, AnyObject>
            {
                if let list = dict["list"] as? [Dictionary<String, AnyObject>]
                {

                    for dictItem in list
                    {
                        if let temp = dictItem["temp"] as? Dictionary<String, Double>
                        {

                            if let maxTemp = temp["max"]
                            {
                                self.weatherForecast.setHighTemp(highTemp: self.convertToString(temp: maxTemp));
                            }

                            if let minTemp = temp["min"]
                            {
                                self.weatherForecast.setLowTemp(lowTemp: self.convertToString(temp: minTemp));
                            }
                        }

                        if let weatherArray = dictItem["weather"] as?
                            [Dictionary<String, AnyObject>]
                        {
                            if let main = weatherArray[0]["main"] as? String
                            {
                                self.weatherForecast.setWeatherType(weatherType: main.capitalized);
                            }
                        }

                        if let date = dictItem["dt"] as? Double
                        {
                            let convertedDate = Date(timeIntervalSince1970: date);
                            self.weatherForecast.setDate(date: convertedDate.dayOfWeek()!);
                        }

                        self.counter += 1;
                        self.arrayOfInts.append(self.counter);
                        self.weatherForecasts.append(self.weatherForecast);
                    }

                    //Array of ints works fine.
                    for integer in self.arrayOfInts
                    {
                        print("Int val is : \(integer)");
                    }
                }
                completed(self.retrievalSuccess(weatherForecasts: self.weatherForecasts));
            }
            else
            {
                completed(self.retrievalFailure(message: "Six day forecast error."));
            }
        }
    }
}

I tried using append using an arrayOfInts and it works fine, there is no overriding which has me stumped as to what is the problem with my WeatherForecasts array.

The issue is that weatherForecast is added several times to your array. Lets say you weatherForecast name is 'X' Your code does this:

1st iteration:

X.day = "Monday"
forecasts.add(X)
//forecasts is now [X]

then if you print all forecasts days it will print "Monday"

2nd iteration:

X.day = "Tuesday"
forecasts.add(X)
//forecasts is now [X,X]

3rd iteration:

X.day = "Wednesday"
forecasts.add(X)
//forecasts is now [X,X,X]

if you print all forecasts days.. it will print "Wednesday,Wednesday,Wednesday"

This happens because you are referencing the same object and updating it .. what you need to do is create a new object on each iteration so that your array looks like this [X,Y,Z] instead of [X,X,X]

try changing this part of your code:

for dictItem in list {

for this:

for dictItem in list {
    weatherForecast = WeatherForecast()

You need to create new WeatherForecast object each time while iterate array

class WeatherService {
    private var weatherForecasts: [WeatherForecast] = [WeatherForecast]()

    public func downloadWeatherForecast(getForecastURL: String, completed: @escaping(_ weatherPayload: WeatherPayload) -> Void) {
        Alamofire.request(getForecastURL).responseJSON { response in
            if let dict = response.result.value as? Dictionary<String, AnyObject> {
                if let list = dict["list"] as? [Dictionary<String, AnyObject>] {
                    for dictItem in list {
                        var weatherForecast = WeatherForecast()
                        if let temp = dictItem["temp"] as? Dictionary<String, Double> {
                            if let maxTemp = temp["max"] {
                                weatherForecast.setHighTemp(highTemp: self.convertToString(temp: maxTemp));
                            }

                            if let minTemp = temp["min"] {
                                weatherForecast.setLowTemp(lowTemp: self.convertToString(temp: minTemp));
                            }
                        }

                        if let weatherArray = dictItem["weather"] as? [Dictionary<String, AnyObject>] {
                            if let main = weatherArray[0]["main"] as? String {
                                weatherForecast.setWeatherType(weatherType: main.capitalized);
                            }
                        }

                        if let date = dictItem["dt"] as? Double {
                            let convertedDate = Date(timeIntervalSince1970: date);
                            weatherForecast.setDate(date: convertedDate.dayOfWeek()!);
                        }

                        self.arrayOfInts.append(self.counter);
                        self.weatherForecasts.append(weatherForecast);
                    }
                }
                completed(self.retrievalSuccess(weatherForecasts: self.weatherForecasts));
            } else {
                completed(self.retrievalFailure(message: "Six day forecast error."));
            }
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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