Dribbler
Dribbler

Reputation: 4701

Append Range in Dictionary to Array in Swift

This works:

var aArray = [ Int ]()
let aRange = ( 0 ... 5 )
aArray.appendContentsOf( aRange )

and produces [0, 1, 2, 3, 4, 5] for aArray.

This however:

enum Dog {
    case Snoopy
    case Lassie
    case Scooby
}

let dogRange = [ Dog.Snoopy : ( 0 ... 5 ), Dog.Lassie : ( 6 ... 11 ), Dog.Scooby : ( 12 ... 17 ) ]

var dArray = [ Int ]()
dArray.appendContentsOf( dogRange[ Dog.Snoopy ] )

throws the error expected an argument list of type '(C)' in Playground and Cannot call value of non-function type '[Dog : ClosedInterval]' in a project in Xcode.

dogRange[ Dog.Snoopy ]

produces 0..<6 in Playground as expected. I can't figure out how to append a Range from a Dictionary as illustrated into an Array. Is this possible, and if so, how?

Many thanks in advance!

Upvotes: 1

Views: 1374

Answers (3)

user3441734
user3441734

Reputation: 17572

an 'alternative' (more functional) way

enum Dog {
    case Snoopy
    case Lassie
    case Scooby
}

let dogRangeDict = [ Dog.Snoopy : ( 0 ... 5 ), Dog.Lassie : ( 6 ... 11 ), Dog.Scooby : ( 12 ... 17 ) ]

let dogRange = dogRangeDict.sort { (dr1, dr2) -> Bool in
    dr1.0.hashValue < dr2.0.hashValue
}.map { (dr) -> [Int] in
    Array(dr.1)
}

print(dogRange[Dog.Lassie.hashValue]) // [6, 7, 8, 9, 10, 11]
print(dogRange[Dog.Scooby.hashValue]) // [12, 13, 14, 15, 16, 17]

so finally dogRange is NOT a Dictionary indexable by Dog.xy, but an immutable (thread safe) Array indexable by Dog.xy.hashValue. You need to unwrap Dictionary value every time, you need it in your next code. This value will be accessible only in the scope, where it is unwrapped. The advantage of an immutable Array indexable by Dog.xy.hashValue will increase with every single usage of some dogRange value

Upvotes: 0

Eric Aya
Eric Aya

Reputation: 70113

Swift Dictionaries always return Optionals. The error message is a bit misleading, but you just need to unwrap:

if let snoopyRange = dogRange[ Dog.Snoopy ] {
    dArray.appendContentsOf( snoopyRange )
}

and no more errors.

Upvotes: 3

user887210
user887210

Reputation:

The issue is that dogRange[ Dog.Snoopy ] produces an optional of type Range<Int>?. In order to use it you need to unwrap it:

enum Dog {
  case Snoopy
  case Lassie
  case Scooby
}

let dogRange = [ Dog.Snoopy : ( 0 ... 5 ), Dog.Lassie : ( 6 ... 11 ), Dog.Scooby : ( 12 ... 17 ) ]

var dArray = [ Int ]()
if let aDog = dogRange[ Dog.Snoopy ] { // unwrap the optional
  dArray.appendContentsOf( aDog )
}

Upvotes: 3

Related Questions