Swift - if string is nil. don't add it to the array
Swift - if string is nil. don't add it to the array
I have an Array
of Image
links -
Array
Image
let alamofireSource = [AlamofireSource(urlString: Img1!)!, AlamofireSource(urlString: Img2!)!,
AlamofireSource(urlString: Img3!)!, AlamofireSource(urlString: Img4!)!]
slideshow.setImageInputs(alamofireSource)
some posts have only one image or two or three, and so on. so, sometimes image 2 (for example) is nil, In that case, I don't want it to be added to the array, is that possible?
3 Answers
3
You can try ( Swift 4 )
let arr = [img1,img2].compactMap{$0}.map{AlamofireSource(urlString:$0)!}
or
let arr = alamofireSource.compactMap{$0}
for Swift 3
let arr = alamofireSource.flatMap{$0}
This is Swift 4. You may want to add flatMap for Swift 3 or prior
– smnk
Jul 3 at 12:08
@SophieBernard Note that the approach in this answer (forcibly unwrapping the result of the initializer) may lead to a run-time exception, as the
AlamofireSource(urlString:)
initializer is a failable initializer. I've added an answer below showing one approach to safely unwrap the result of the possibly failing initialization, taking also into account the fact that the url strings themselves (Img1
, ... Img4
in your example) are optionals, and should also be safely unwrapped.– dfri
Jul 7 at 23:10
AlamofireSource(urlString:)
Img1
Img4
so, sometimes image 2 (for example) is nil, In that case, I don't want
it to be added to the array, is that possible?
Yes it is. Although I would go with Sh_Khan's suggestion to use the compactMap
method to achieve it, but it would be useless for your current case:
compactMap
Based on your code snippet, I'd assume that alamofireSource
of type [AlamofireSource]
, but not [AlamofireSource?]
and that's because you are forcibly unwrap its elements (by adding !
to each of its elements). So far alamofireSource
doesn't contain nils (actually it could be more danger than just a declaration, your app might crash!)
alamofireSource
[AlamofireSource]
[AlamofireSource?]
!
alamofireSource
So first of all, I would recommend to remove the !
from alamofireSource
:
!
alamofireSource
let alamofireSource = [AlamofireSource(urlString: Img1!),
AlamofireSource(urlString: Img2!),
AlamofireSource(urlString: Img3!),
AlamofireSource(urlString: Img4!)]
which means let it be as [AlamofireSource?]
, therefore you would gain the benefit of using compactMap(_:)
:
[AlamofireSource?]
compactMap(_:)
Returns an array containing the non-nil results of calling the given
transformation with each element of this sequence.
As:
let alamofireSourceWihoutNils = alamofireSource.compactMap { $0 }
Assuming you put your Optional
url strings into an array, say urlStrings
(of type [String?]
), you can construct alamofireSource
according to (Swift 4):
Optional
urlStrings
[String?]
alamofireSource
let alamofireSource = urlStrings.compactMap { $0.map(AlamofireSource.init) }
Which make use of the map(_:)
operator of Optional
and compactMap(_:)
to unwrap the two-level optionality.
map(_:)
Optional
compactMap(_:)
Details
Your example contains two levels of optionality:
ImgX
String?
img1
img4
CapitalFirstLetter
init?(urlString: String, placeholder: UIImage? = nil)
AlamofireSource
First of all, lets gather the optional image links (imgX
) into an array
imgX
let urlStrings = [url1, url2, url3, url4] // [String?]
You can combine the map(_:)
operator of Optional
with compactMap(_:)
to safely unwrap and make use of the .some
entires of urlStrings
, thereafter collect the successful invocations of the failable initializer of AlamofireSource
:
map(_:)
Optional
compactMap(_:)
.some
urlStrings
AlamofireSource
let alamofireSource = urlStrings.compactMap { $0.map(AlamofireSource.init) }
// or, use a named closure argument
let alamofireSource = urlStrings.compactMap { str in str.map(AlamofireSource.init) }
If using Swift 3, replace the compactMap(_:)
invocation above with flatMap(_:)
:
compactMap(_:)
flatMap(_:)
let alamofireSource = urlStrings.flatMap { $0.map(AlamofireSource.init) }
// or, use a named closure argument
let alamofireSource = urlStrings.flatMap { str in str.map(AlamofireSource.init) }
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Thanks a trillion! It fixed the problem :-)
– Sophie Bernard
Jul 3 at 10:22