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}





Thanks a trillion! It fixed the problem :-)
– Sophie Bernard
Jul 3 at 10:22





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.

Popular posts from this blog

api-platform.com Unable to generate an IRI for the item of type

How to set up datasource with Spring for HikariCP?

Display dokan vendor name on Woocommerce single product pages