Romain Sickenberg
Romain Sickenberg

Reputation: 140

Sorting a Swift array by suggested key

I'm blocked on an issue. It began with TableView moving row logic so I have to reflect it into my model and then save the row in UserDefaults.

Later, I'm reusing the index saved into UserDefaults and I want to reorder my array with this index.

Basically I tried this:

// in a commands.keys loop -> stack
// in a commands[stack]! loop -> command
guard let suggestedIndex = AllCommands.getCommandStackIndex(commandId: command.id) else { continue }
guard let oldIndex = commands[stack]!.firstIndex(where: { $0.id == command.id }) else {
    fatalError()
}

commands[stack]!.insert(commands[stack]!.remove(at: oldIndex), at: suggestedIndex)

And I also tried arr.swap(Int, Int) but it was unsuccessful.

I'm facing Array index out of range and I would like to know if there is a better option to achieve this or fix this issue.

static func getCommandStackIndex(commandId: Int) -> Int? {
    UserDefaults.standard.object(forKey: "command_\(commandId)_index") as? Int
}

static func setCommandPosition(commandId: Int, stack: ActionViewStackPosition, stackIndex: Int) {
    UserDefaults.standard.removeObject(forKey: "command_\(commandId)_index")
    UserDefaults.standard.removeObject(forKey: "command_\(commandId)_stack")

    UserDefaults.standard.set(stackIndex, forKey: "command_\(commandId)_index")
    UserDefaults.standard.set(stack.rawValue, forKey: "command_\(commandId)_stack")

    print("--- Saved occurrence for id: [\(commandId)] in index: [\(stackIndex)] & stack: [\(stack)] ---", #function)
}
// SettingsTableViewController

private func saveNewPositions(before: IndexPath, new: IndexPath) {
    guard let command = commands[before.section]?[before.row] else {
    print("Missed align between [\(before.section)][\(before.row)]")
    return
}

    var section: ActionViewStackPosition
    switch new.section {
    case 0:
        section = .top
    case 1:
        section = .bottom
    case 2:
        section = .inactive
    default:
        fatalError("Hun?")
    }

    AllCommands.setCommandPosition(commandId: command.id, stack: section, stackIndex: new.row)
}

// Called by
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
    saveNewPositions(before: sourceIndexPath, new: destinationIndexPath)
}

Regards

Upvotes: 0

Views: 77

Answers (1)

janakmshah
janakmshah

Reputation: 151

If you need to have two items in an array change places, the swapAt() method is exactly what you want: provide it two indexes inside your array, and the items at those positions will be swapped.

For example, consider this array:

var names = ["Paul", "John", "George", "Ringo"]

If I wanted John and Paul to swap places, I’d swap positions 0 and 1, like this:

names.swapAt(0, 1)

Note: swapAt() will trigger a fatal error if you try to swap beyond the length of the array. What was your suggestedIndex? Perhaps it was outside the bounds of your array? Try adding a check to make sure the two indexes you’re trying to swap are actually within the bounds of the array.

https://developer.apple.com/documentation/swift/array/2893281-swapat

Upvotes: 2

Related Questions