0

I'm trying to get the count of an optional array as a string, or nil if the array is nil.

This works:

let array: [AnyObject]? = ...

textLabel.text = (array != nil ? String((array?.count)!) : nil)

But it looks ridiculous. Is there some nicer way to write this (still as a one-liner)?

Edit: I expect the text to be "3" not "Optional(3)", for example.

In Objective C, this could be (array ? [@(array.count) stringValue] : nil).

jrc
  • 20,354
  • 10
  • 69
  • 64

1 Answers1

5

Just do this:

textLabel.text = array?.count.flatMap { String($0} }

flatMap on an optional will return either nil (if the optional was nil) or the result of running the closure and passing the optional as the argument.

Edit to surface other possible answers from the comments —jrc

  • array.map { String($0.count) }Kurt Revis
  • (array?.count).map { String($0) }Martin R.
Community
  • 1
  • 1
Catfish_Man
  • 41,261
  • 11
  • 67
  • 84
  • Even better, just use map: array.map { String($0.count) } – Kurt Revis Oct 18 '15 at 22:00
  • Hmm, I get `Value of type 'Int' has no member 'flatMap'` on `count`. – jrc Oct 18 '15 at 22:17
  • 1
    His `array` is really an Optional, so array.map() means Optional.map not Array.map, doesn't it? It worked for me in a playground, anyway. – Kurt Revis Oct 18 '15 at 22:17
  • 1
    For some reason unknown to me you need parentheses: `(array?.count).flatMap { String($0) }` (and `map()` would work as well, there is no difference in *this* case because the closure does not return an optional). – Martin R Oct 18 '15 at 22:20
  • Thanks guys. `(array?.count).map { String($0) }` works and is even readable. – jrc Oct 18 '15 at 22:29
  • Ah right. Missed that you said array.map rather than array?.map. Subtle, but nice. – Catfish_Man Oct 19 '15 at 00:22
  • Oh. Sorry @Kurt Revis. Aha, I didn't know you could call `map` on optionals! Very cool. Thanks guys. – jrc Oct 19 '15 at 01:57