简体   繁体   中英

Swift: Sorting an array of objects retrieved from the backend based off their ids held in another created array in the frontend

I have created an array of ids that represents the order of objects that a user has reorganized the cells inside of a tableview. I have saved this into the UserDefaults, as shown below.

let index = allAnimals.map { $0.id }
UserDefaults.standard.set(index, forKey:"sorted")

When the screen loads, it runs this function, which retrieves the objects from the backend and appends them to allAnimals.

func getAllAnimals(barnId: String){
        let userid = UserDefaults.standard.string(forKey: "userid")!
        let params:[String:Any] = ["userid":userid,
                                   "barnid": barnId]
        
        print(Endpoint.getAllAnimals)
        print(params)
        
        showLoading()
        HTTPClient().post(urlString: Endpoint.getAllAnimals, params: params, token: nil) { [weak self](data, error) in
            self?.hideLoading()
            if(error != nil){
                print(error!.localizedDescription)
                return
            }
            if(error == nil && data != nil){
                let json = JSON(data!)
                print(json)
                let status = json["status"].stringValue
                if(status == "error"){
                    //self?.showAlert(message: json["message"].stringValue)
                    return
                }
                self?.allAnimals.removeAll()
                json["data"].array?.forEach({ (subJson) in
                    subJson["swines"].array?.forEach({ (swineJson) in
                        let animal = Animal(json: swineJson, type: "swine")
                        self?.allAnimals.append(animal)
                    })
                    subJson["cattles"].array?.forEach({ (cattleJson) in
                        let animal = Animal(json: cattleJson, type: "cattle")
                        self?.allAnimals.append(animal)
                    })
                    subJson["sheeps"].array?.forEach({ (sheepJson) in
                        let animal = Animal(json: sheepJson, type: "sheep")
                        self?.allAnimals.append(animal)
                    })
                    subJson["goats"].array?.forEach({ (goatJson) in
                        let animal = Animal(json: goatJson, type: "goat")
                        self?.allAnimals.append(animal)
                    })
                })
                print(self?.allAnimals.map { $0.id } as Any)
                self?.tableView.reloadData()
            }
        }
    }

I want to reorder the objects by their id, which is represented by the index array I have saved into UserDefaults, but currently when it reloads it is ordered by id by default through the backend. How can I reorder the tableview based on this new array of ids that I have created? I have played around with.sort() but cannot figure it out. Also, the function in the backend is not specifying how to order the array, it just by default grabs them by id ascending.

You don't tell us what you save to UserDefaults. If there is an ID field in the data that you download, you could save an array of those IDs to userDefaults in the order the user put them in.

You could then:

Read the array of IDs from UserDefaults. Let's call this sortedIDs

Read the array of items from the back-end. Let's call this array ServerStructsArray

Assuming the records you read are structs named ServerStruct :

struct ServerStruct {
    let id: Int  //Assume the ID is an Int. 
    //whatever fields
    let value1: String
}

In the completion handler of the network read:

Convert the array of the full records to a dictionary with the ID as the key:

var serverStructsDict = [Int : ServerStruct]()

for item in ServerStructsArray {
   serverStructsDict[item.key] = item
}

For each entry in the array from UserDefaults, get an ID and use it as a key to fetch an item from your dictionary of full records. No need to sort again.

If you do want to sort your array of items that you read from the back-end:

Assume that the dictionary of ServerStructs is called serverDict

let sortedArray: [ServerStruct] = sortedIDs.map { serverDict[$0]! }

You now have the records from the server restored to the order you saved to UserDefaults .

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