ikevin8me
ikevin8me

Reputation: 4313

Swift language: nil check, and if so instantiate new object

Is there any way I can simplify this:

var unloadedImagesRows = [String:[Int]]()

private func addToUnloadedImagesRow(row: Int, forLocation:String!) {
    if unloadedImagesRows[forLocation] == nil {
                    unloadedImagesRows[forLocation] = [Int]()
    }
    unloadedImagesRows[forLocation]!.append(row)
}

Doesn't Swift have an easy way to check for nil, and if so, create a new object, and all subsequent uses refers to the object?

Upvotes: 10

Views: 3257

Answers (6)

Eric Mentele
Eric Mentele

Reputation: 1060

var unloadedImagesRows = [String:[Int]]()

// if let
private func addToUnloadedImagesRow(row: Int, forLocation:String!) {
    if let _ = unloadedImagesRows[forLocation] {

    } else {
        unloadedImagesRows[forLocation] = [Int]()
    }
    unloadedImagesRows[forLocation]!.append(row)
}

// guard let
private func addToUnloadedImagesRow(row: Int, forLocation:String!) {
    guard let _ = unloadedImagesRows[forLocation] else {
        unloadedImagesRows[forLocation] = [Int]()
        return addToUnloadedImagesRow(row, forLocation: forLocation)
    }

    unloadedImagesRows[forLocation]!.append(row)
}

// nil coalescing
private func addToUnloadedImagesRow(row: Int, forLocation:String!) {
    var b = unloadedImagesRows[forLocation] ?? [Int]()
    b.append(row)
    unloadedImagesRows[forLocation] = b
}

Upvotes: 2

Eendje
Eendje

Reputation: 8883

You can simplify it into just one line:

private func addToUnloadedImagesRow(row: Int, forLocation:String!) {
    unloadedImagesRows[forLocation] = (unloadedImagesRows[forLocation] ?? []) + [row]
}

Upvotes: 8

nebs
nebs

Reputation: 4989

If you want to avoid if or guard you could try the nil coalescing operator (??).

private func addToUnloadedImagesRow(row: Int, forLocation:String!) {
    var rowsForLocation = unloadedImagesRows[forLocation] ?? [Int]();
    rowsForLocation.append(row)
    unloadedImagesRows[forLocation] = rowsForLocation
}

Note: This might not be very efficient since you have to re-assign the array to the dictionary. I'm not sure if this will result in a full copy of the array.

Upvotes: 2

Rahul Katariya
Rahul Katariya

Reputation: 3628

You can create a helper operator for nil checks and use it like below.

infix operator ?= { associativity left precedence 160 }

func ?=<T: Any>(inout left: T?, right: T) -> T {
    if let left = left {
        return left
    } else {
        left = right
        return left!
    }
}

Here you will be able to use it like unloadedImagesRows[forLocation] ?= [Int]() if empty

var unloadedImagesRows = [String:[Int]]()

private func addToUnloadedImagesRow(row: Int, forLocation:String!) {
    unloadedImagesRows[forLocation] ?= [Int]()
    unloadedImagesRows[forLocation]!.append(row)
}

addToUnloadedImagesRow(1, forLocation: "This is something")

print(unloadedImagesRows) // "["This is something": [1]]\n"

Upvotes: 3

Bhavin Bhadani
Bhavin Bhadani

Reputation: 22374

you can use if let or guard statement

  private func addToUnloadedImagesRow(row: Int, forLocation:String!) {
      if let a = unloadedImagesRows[forLocation] as? [Int] {
           //...success block
      }
  }

or use guard statement

  private func addToUnloadedImagesRow(row: Int, forLocation:String!) {
      guard let a = unloadedImagesRows[forLocation] else {
           return
      }
      //...
  }

for more info. check this link

Upvotes: 1

Mahendra
Mahendra

Reputation: 8914

You can check it as follow.

private func addToUnloadedImagesRow(row: Int, forLocation:String!) {
    if let image = unloadedImagesRows[forLocation] {
                //it is not nil
    } else {
        //it is nil
    }

}

Upvotes: 1

Related Questions