1

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!

3 Answers 3

3

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.

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

Comments

3

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 )
}

Comments

0

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

2 Comments

This is quite a roundabout method of adding a range of values to an array. How is this more functional? Does it provide any additional value beyond the other answers?
@KennethBruno (a) there is no variable, which could be modified (b) ones arr is created, you can access requested [Int] value by subscript based on your enumeration. (c) there is no need to unwrap the value. By the way enum Dog with associated value of Range<Int> or better [Int] will be here the best solution. I voted for Eric's answer, because it explains where is the trouble, but better is to avoid the trouble ...

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.