0

I have a mutable array:

var responseArray = ["yes", "no", "no way", "of course", "for sure", "not a chance", "positively"]

The responseArray is the data source for my table view which allows for multiple selections during editing.

I am capturing the selected index paths:

let paths = tableView.indexPathsForSelectedRows()

I can return and verify each selected indexPath of my tableView by running println(paths).

I have read the documentation for the indexPathsForSelectedRows method and understand that it returns an array of index paths which I have sorted by row.

What I cannot understand is how I can use the returned array of index paths to remove the data from the responseArray for each row that is selected for deletion in the table view.

After reading through some documents, is it correct of me to believe that I cannot remove any data from the `responseArray' as I am enumerating over it? For example:

@IBAction func deleteButtonPressed(sender: AnyObject) {
    if responseArray.count > 0 {
        if let paths = self.tableView.indexPathsForSelectedRows() {
            var sortedArray = paths.sorted({$0.row < $1.row})
            // Remove index paths from responseArray
            for i in sortedArray {
                responseArray.removeAtIndex(i.row)
            }
            self.tableView.reloadData()
        }
    }
}

I am able to remove each row from the table view one by one, but when I select the first and last rows, all of the rows, or any other combination of rows for deletion, I get fatal error: Array index out of range. However, if I select two adjacent rows for deletion, the desired result is achieved and those two rows are removed from the table view.

I know that there is something that I am missing, but as a new programmer I have been unable to resolve this issue for three days now. What is it that I am not doing correctly?

3 Answers 3

3

Here's your array: [ A, B, C, D ]

Let's say you want to delete A and D at index 0 and 3 respectively, one at a time:

deleteAtIndex(0) gives: [ B, C, D ]

deleteAtIndex(3) gives: Out of bounds exception

Edit: Ok, to avoid complicating things, why not just always delete the highest index first by reversing your sort: {$1.row < $0.row}

Sign up to request clarification or add additional context in comments.

1 Comment

I definitely understand how that will throw an exception. However, I am not sure how I can use the array to remove all of the selected indexes at once because the array only has four methods to remove items: removeAll(), removeAtIndex(), removeLast(), and removeRange().
1

For future reference, in addition to the answers given already you could simplify it further by reversing the selected indices:

@IBAction func deleteButtonPressed(sender: AnyObject) {
    self.tableView.selectedRowIndexes.reverse().forEach { x in
        responseArray.removeAtIndex(x)
    }
    self.tableView.reloadData()
}

Comments

0

Since your paths array is sorted, you know that every time you delete an element from the array, higher indices will now be one less than they were. You can simply keep an incrementing offset to apply to your deletions -

@IBAction func deleteButtonPressed(sender: AnyObject) {
    if responseArray.count > 0 {
        if let paths = self.tableView.indexPathsForSelectedRows() {

            var sortedArray = paths.sorted({$0.row < $1.row})
            var offset=0;
            // Remove index paths from responseArray
            for i in sortedArray {
                responseArray.removeAtIndex(i.row-offset)
                offset++
            }
            self.tableView.reloadData()
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.