0

I have a parameter for a method that is of type Range<Int>? that defaults to nil. I'd like a nice succinct way of saying "Use the given range or use the whole range". Nothing I've done seems to quite work, I feel like this should though...

class func fileNames(entries: Array<DBFILESMetadata>, range: Range<Int>? = nil) -> Array<String> {
    return entries[range ?? 0... as Range<Int>].map{ $0.name }.filter{ $0.hasSuffix(".jpg") }
}

...I get the error Cannot convert value of type 'CountablePartialRangeFrom<Int>' to type 'Range<Int>' in coercion, which I totally get, but then why does this work (via pattern #6 here: https://stackoverflow.com/a/42860580/84783)

let array = ["a", "b", "c"]
let range = 1...
let arraySlice = array[range]

I can just do this in a conditional, but feel like a one liner should work.

rob5408
  • 2,972
  • 2
  • 40
  • 53

1 Answers1

1

You can just change your method parameter to CountableRange and pass the array indices property in case of nil:

class func fileNames(entries: Array<DBFILESMetadata>, range: CountableRange<Int>? = nil) -> Array<String> {
    return entries[range ?? entries.indices].map{ $0.name }.filter{ $0.hasSuffix(".jpg") }
}
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • I don't know that i am right or not but `CountableClosedRange` should be there at `CountableRange` because `CountableRange` will not contain upperbounds like 0..<8 value in range would be 0 - 7 – Prashant Tukadiya Jan 22 '18 at 05:28
  • Thats how it is. You could also use `CountableClosedRange` but you would need to pass a `CountableClosedRange` also after the nil coalescing operator – Leo Dabus Jan 22 '18 at 05:30
  • This does work actually and works for what I want. Any idea why something like `["a", "b", "c"][1...]` works though? – rob5408 Jan 22 '18 at 05:31
  • You said that you needed the whole range in case of nil. What is the parameter type you would like to use in your method? You need to provide a method for each if you would like to be able to use more than one type. This might help you to understand what I mean https://stackoverflow.com/questions/24092884/get-nth-character-of-a-string-in-swift-programming-language/38215613?s=1|43.6266#38215613 – Leo Dabus Jan 22 '18 at 05:32
  • No I mean based on the docs Array `subscript` wants an `Int` or a `Range`, but passing it `CountablePartialRangeFrom` is fine. There's some jump I'm missing as to why that's ok. Know what I mean? – rob5408 Jan 22 '18 at 05:40
  • If you would like to use `CountableClosedRange` you need to provide a default of the same type such as `range ?? entries.startIndex...(entries.index(entries.endIndex, offsetBy: -1, limitedBy: entries.startIndex) ?? entries.startIndex)` – Leo Dabus Jan 22 '18 at 05:41
  • @LeoDabus, I think you're responding to something Prashant said above. – rob5408 Jan 22 '18 at 05:42
  • 1
    No I am saying that you need to implement all the methods if you would like to be able to call that method with `CountableRange` , `CountableClosedRange`, `PartialRangeUpTo`, `PartialRangeThrough` and `PartialRangeFrom`. When using the nil coalescing operator the default value needs to match the value type that precedes the `??` operator – Leo Dabus Jan 22 '18 at 05:45
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/163609/discussion-between-rob5408-and-leo-dabus). – rob5408 Jan 22 '18 at 05:47