Swift: optional array counter

In Objective-C, if I had the following property:

@property (strong, nonatomic) NSArray * myArray; 

The method to return the number of objects in myArray will look like this:

 - (NSInteger) numberOfObjectsInMyArray { return [self.myArray count]; } 

This will return either the number of objects in the array, or 0 if myArray == nil ;

The best equivalent I can come up with for this in Swift:

 var myArray: Array<String>? func numberOfObjectsInMyArray() -> Int { return myArray ? myArray!.count : 0 } 

So, checking an optional array contains a value, and if so expand the array and return this value, otherwise return 0.

Is this the right way to do this? Or is there something simpler?

+6
source share
3 answers

It looks like an easier way.

Objective-C code is shorter only because nil also a form 0, which is a C language.

Since swift is strongly typed, you do not have such a shorthand. In this particular case, this requires a little more effort, but overall it saves you from most of the headaches caused by the lack of typing.


As for the specific case, is there any reason to make the array optional in the first place? You may have an empty array. Something like this might work for you:

 var myArray: Array<String> = [] func numberOfObjectsInMyArray() -> Int { return myArray.count } 

( Source for this information )

+6
source

Try using the nil coalescing statement .

According to Apple documentation:

The nil coalescing (a? B) statement expands optional a if it contains a value, or returns the default value b if a is nil.

So your function might look like this:

  func numberOfObjectsInMyArray() -> Int { return (myArray?.count ?? 0) } 

I agree with others that this may be a bad idea for a number of reasons (for example, it looks like there is an array with the number “0” when there really is no array), but even bad ideas need to be implemented.

EDIT:

So, I am adding this because two minutes after I posted this answer, I came across a reason to do what the author wants to do.

I am implementing the NSOutlineViewDataSource protocol in Swift. One of the features required by the protocol:

optional func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: AnyObject?) -> Int

This function requires the return of the number of children from the item parameter. In my code, if an element has any children, they will be stored in an array, var children: [Person]?

I will not initialize this array until I add it to the array.

In other words, while I am providing NSOutlineView data, children may be nil , or it may be filled, or it may be once filled, but subsequently all objects have been removed from it, in which case it will not be nil , but it count will be 0 . NSOutlineView doesn't care if children - nil - all he wants to know is how many lines it takes to display item children .

So, in this situation, it makes sense to return 0 if children is nil . The only reason to call the function is to determine the number of NSOutlineView lines. It doesn't matter if the answer is 0 , because children is zero or because it's empty.

return (children?.count ?? 0) will do what I need. If children is nil , it will return 0 . Otherwise, it will return count . Excellent!

+25
source

How to use optional for return value?

 var myArray: Array<String>? func numberOfObjectsInMyArray() -> Int? { return myArray?.count } 

I think this method is safer.

( Source for this information )

+3
source

Source: https://habr.com/ru/post/971535/


All Articles