Bubble sorting array in Swift, compiler error while swapping

I wrote a very simple bubble for a card game. It takes an array of Map objects, each with an order attribute that specifies the value to be sorted for this game.

The following code stopped compiling for a while between Swift Beta 1 and Beta 6 and I'm not really sure why.

 ///Sort the cards array by order
  func sortCards(cards: Array<Card>) -> Array<Card> {
    var sorted = false
    while sorted == false {
      sorted = true
      for i in 0...cards.count - 2 {
        if cards[i].order > cards[i+1].order {
          sorted = false
          var first = cards[i]
          var second = cards[i + 1]
          cards[i] = second    //ERROR
          cards[i + 1] = first //ERROR
        }
      }
    }
    return cards
  }

      

The lines where the swap occurs are triggered with a very cryptic message:

@!value $T5 is not identical to 'Card'

What has changed and what am I doing wrong here?

Bonus question: how am I supposed to understand the error message?

+3


source to share


4 answers


If you declare such a function, then the array defies. You need to use the keyword inout

like this:

func sortCards(inout cards: Array<Card>) -> Array<Card> {
//code
}

      

Then you call it with &

:

sortCards(&myArray)

      

Explanation



The whole array model and skip by value / reference changed during the beta process.

In beta 1, arrays passed to subroutines were just passed by value. Arrays passed by value (and let them be arrays) can still be changed if you haven't changed the length of the array, thereby breaking the rules for passing by value and allowing your original code to work.

In Beta 4 I believe it was, they changed the arrays to always be passed by value and change persistent arrays (let it be) really unmodifiable, which caused your code to fail and crash at compile time ...

The keyword inout

changes the array to be passed by reference instead of a value and changes it to implicitly defined with let to defined with var, which means the array is now modified and the changes to the array are visible to the caller.

+1


source


Functional parameters are constant by default (as if declared with let

). If you want to change a parameter inside your function, you must declare it as a variable:

func sortCards(var cards: Array<Card>) -> Array<Card> { ...

      



Note that only the local parameter has changed cards

, not the array passed as an argument to the function (which seems to be your intention because the function is returning a new array).

+3


source


I played around with the following using quick 3. Hope this helps some people who come here.

sorting bubbles:

func bubble(arr: inout [Int]) {
    for i in (1..<arr.count).reversed() {
        for j in 0..<i where arr[j] > arr[j + 1] {
            swap(&arr[j], &arr[j + 1])
        }
    }
}

      

using step:

func bubbleStride(arr: inout [Int]) {
    for i in stride(from: arr.count - 1, to: 1, by: -1) {
        for j in 0..<i where arr[j] > arr[j + 1] {
            swap(&arr[j], &arr[j + 1])
        }
    }
}

      

using while:

func bubbleWhile(arr: inout [Int]) {
    var i = arr.count - 1
    while(i > 0) {
        var j = 0
        while(j < i) {
            if arr[j] > arr[j + 1] {
                swap(&arr[j], &arr[j + 1])
            }
            j += 1
        }
        i -= 1
    }
}

      

This can be used to generate a random array of integers:

import Cocoa

func ints(cnt: Int, ceiling: Int) -> [Int] {
    let arr = Array(repeating: 0, count: cnt)
    return arr.map { _ in Int(arc4random_uniform(UInt32(ceiling))) }
}

      

eg:.

let a = ints(cnt: 10, ceiling: 100)
print(a)

var b = a
bubble(arr: &b)
print(b)

      

output:

[13, 30, 68, 19, 1, 4, 28, 65, 96, 13]
[1, 4, 13, 13, 19, 28, 30, 65, 68, 96]

      

+2


source


Here is the bubble sort in swift 4.0.2

var array = [15,11,20,14,12,13,17,16,18,19]
var sortedArray = Array(array)
var sortedAboveIndex = array.count 

for i in 0 ..< sortedAboveIndex-1 {

  for j in 0 ..< sortedAboveIndex-i-1 {

      if (sortedArray[j] > sortedArray[j+1]) {

          sortedArray.swapAt(j, j+1)        
      }
  }

}

print(sortedArray)

      

if any requests for the above code please comment below

0


source







All Articles