如何识别从集合(数组)中删除的对象?

时间:2018-09-17 07:36:40

标签: ios arrays swift

我有以下代码来处理拉动以刷新响应

let copyData = data.reversed() // it is pull to refresh response (load page 1)
for (_,element) in copyData.enumerated() {
    let foundElement = allObjects.filter{$0.id == element.id} // Find  element in main array
    if let firstElement = foundElement.first, let index =   allObjects.index(of: firstElement) {
        allObjects[index] = element // Replace if found
    } else {
        allObjects.insert(element, at: 0) // Insert if not found 
    }
}


self.arrayPosts = allObjects 

其中data是可编码类,它是请求刷新的API响应。 allObjects是带有分页的预加载数据

问题:假设在allObjects中我有50个对象(5页,每10个ID为(1至50)) 用户拉动刷新,然后我从API(ID 1,2,3,4,5,6,7,10,11)加载第一页,然后如何识别删除哪个对象(8,9)

我应该将allObjects的第十个索引与data的第十个索引对象的ID进行比较吗?

有更好的处理方法吗?请建议

3 个答案:

答案 0 :(得分:5)

不比较页面(一次比较10个项目)-如果添加/删除一个项目,页面将不同步,最终会丢失/重复对象。

大概您的对象是按某个键/日期等排序的。

  • 在上次下载的对象中获取密钥的值。
  • 使用键<=最后一个键将所有现有对象复制到新数组中。
  • 将下载的阵列与此子阵列进行比较。
  • 已下载阵列中不在子阵列中的对象应被删除。

答案 1 :(得分:0)

这是我的处理方式。初次阅读时,代码非常复杂,但添加了注释即可理解

func handleResponse(page:Int,isForRefersh:Bool = false, data:Array<InspirePost>) {


        guard data.count != 0 else {
            // Check if we are requesting data from pull to referesh and First page is empty then we don't have data to show change state to empty

            if self.arrayPosts.count == 0  || (isForRefersh && page == 1) {
                self.state = .empty
                self.tableView.reloadData()

            } else {
                self.state = .populated(posts: self.arrayPosts)

            }
            return
        }

        // Now we need to check if data called by referesh control then
        //1) Replace object in array other wise just append it.

        var allObjects = self.state.currentPost

        if isForRefersh {
            // If both array Has same number of element i.e both has page one loaded
            if data.count >= allObjects.count {
                allObjects = data
            } else {
                let copyData = data.reversed()
                for (_,element) in copyData.enumerated() {
                    if let index = allObjects.firstIndex(where: {$0.id == element.id}) {
                        allObjects[index] = element // Replace if found
                    } else {
                        allObjects.insert(element, at: 0) // Insert if not
                    }

                }

                let minID = data.min(by: {$0.id ?? 0 < $1.id ?? 0})?.id

                // DELETE item
                let copyAllObject = allObjects
                for (_,element) in copyAllObject.enumerated() {
                    guard let id = element.id, id >=  minID  ?? 0 else {
                        continue
                    }
                    if !data.contains(element) {
                        if let indexInMainArray = allObjects.index(where: {$0.id == id}) {
                            allObjects.remove(at: indexInMainArray)

                        }
                    }
                }
            }

            //When we pull to refersh check the curent state

            switch self.state {
            case .empty,.populated : // if empty or populated set it as populated (empty if no record was avaiable then pull to refersh )
                self.state = .populated(posts: allObjects)
            case .error(_, let  lastState) : // If there was error before pull to referesh handle this
                switch lastState {
                case .empty ,.populated: // Before the error tableview was empty or popluated with data
                    self.state = .populated(posts: allObjects)
                case .loading,.error: // Before error there was loading data (There might more pages if it was in loading so we doing paging state ) or error
                    self.state = .paging(posts: allObjects, nextPage: page + 1)
                case .paging(_,let nextPage): // Before error there was paging then we again change it to paging
                    self.state = .paging(posts: allObjects, nextPage: nextPage)


                }
            case .loading: // Current state was loading (this might not been true but for safety we are adding this)
                self.state = .paging(posts: allObjects, nextPage: page + 1)
            case .paging(_,let nextPage): // if there was paging on going don't break anything
                self.state = .paging(posts: allObjects, nextPage: nextPage)

            }

            self.arrayPosts = allObjects



        } else {
            allObjects.append(contentsOf: data)
            self.isMoreDataAvailable = data.count >= self.pageLimit

            if self.isMoreDataAvailable {

                self.state = .paging(posts: allObjects, nextPage: page + 1)

            } else {
                self.state = .populated(posts: allObjects)
            }
            self.arrayPosts = self.state.currentPost
        }

        self.tableView.reloadData()

    }

我在哪里

indirect enum PostListStatus {
    case loading
    case paging(posts:[InspirePost],nextPage:Int)
    case populated(posts:[InspirePost])
    case error (error:String,lastState:PostListStatus) // keep last state for future if we need to know about data or state
    case empty


    var currentPost:[InspirePost] {
        switch self {
        case .paging(let posts ,  _):
            return posts
        case .populated( let posts):
            return posts
        case .error( _, let  oldPost) :
            switch oldPost {
            case .paging(let posts ,  _):
                return posts
            case .populated( let posts):
                return posts
            default:
                return []
            }

        default:
            return []
        }
    }

    var nextPage : Int {
        switch  self {
        case .paging(_, let page):
            return page
        default:
            return 1
        }
    }

}

答案 2 :(得分:-1)

您可以同时为setallObjects制作data。然后在subtracting(_:)中使用set方法来查找丢失的方法。 从主阵列中删除那些丢失的阵列并使用它。一旦有了正确的主数组元素,就在显示时对其进行分页。