Convert/add string to a specific type - arrays

I would like to convert/add a string to a type [Talent.Otherlanguages]
Talent.Otherlanguages is an enum who contain many languages.
I would like to do this : otherlanguages?.append(Talent.Otherlanguage(rawValue: langue)!)
but when i do print(otherlanguages) the value is set to nil.
Do any of you have an idea to help me ?

In case you consider otherlanguages is nil it is my assamtion. Because if you send wrong rawValue to the enum constructor you going to receive crash.So you are not checking if otherlanguages is not nil and try to append something.
This is example:
enum Languages:String {
case uk = "english "
case ua = "ukrainian"
}
var languages = [Languages]()
print(languages) //[]
languages.append(Languages(rawValue: "ukrainian")!)
print(languages) //[Languages.ua]

Related

Null conditional in Motoko?

Getting the following error:
expression of type
?Product/798
cannot produce expected type
{id : Nat; name : Text; price : Nat; sku : Text}
when trying to loop over a list of ids, get the corresponding HashMap value, and add to a new array only if the get() function returns a Product.
for (id in productIds.vals()) {
var product: ?Product = products.products.get(id);
if (product != null) {
products_list := Array.append<Product>(products_list, [product]);
};
};
Am I maybe misunderstanding the best way to approach this? It seems like I shouldn't get any errors because if it's not a Product type (which is the "expected type" it references) it should just continue on, right?
The variable product is of type ?Product, but your instantiation of the Array.append function expects an array of values of plain type Product.
The comparison with null does not magically change the type of the variable. You'll need to pattern-match it with a switch to extract the actual value:
switch product {
case (?p) { products_list := Array.append<Product>(products_list, [p]) };
case null { ...do something else... };
}

Swift: Is it a good idea to use enum's raw value to access a UIButton and a string from a constant array?

I apologize in advance, this is hard to explain. I will provide more detail if needed.
This is the Constants struct that I use to reference UIButtons in a collection array and use as keys for dictionaries.
struct Constants {
static let scoreA = "score_a"
static let scoreB = "score_b"
static let scoreC = "score_c"
static let scoreD = "score_d"
static let constantsArray = [kScoreA, kScoreB, kScoreC, kScoreD]
enum Scores: Int, CaseIterable { case scoreA = 1, ScoreB, ScoreC, ScoreD}
}
My initial view controller has a lot of UIButtons. All the score UIButtons are tagged from 1 and up. The UIButtons are hooked to an IBOutlet UIButton array. This way I can avoid having too many IBOutlets
#IBOutlet var collectionOfScoreButtons: Array<UIButton>!
I reference the UIButtons using code like this throughout my App.
if let scoreAButton = collectionOfScoreButtons[Constants.Scores.scoreA.rawValue - 1]
The UIButtons order is the same as the enum's order e.g. scoreA is the first item in the enum and scoreA button is the first button in the array.
And I can retrieve a dictionary key like this, so I can update its value
// after pushing a score button
func handleScoreValue(tag: Int) {
let scoreKey = Constants.constantScoreArray[tag - 1]
dictionary[scoreKey, default: 0] += 1
}
I am not sure if there is a better way to handle this situation. The code works well, but I feel like there is a better way.
I can't see any advantage of using Scores enum to get reference for certain button, you have to specify index anyway
if let scoreAButton = collectionOfScoreButtons[0]
also you can make your Constants enum and implement CaseIterable protocol which allows you to make array of all enum's cases using Enum.allCases
enum Score: String, CaseIterable {
case A = "score_a"
case B = "score_b"
case C = "score_c"
case D = "score_d"
}
then I believe you have IBAction for your button so you can get index of sender in your array of buttons. Then you don't have to set tag of UIButton
#IBAction func buttonPressed(_ sender: UIButton) {
if let index = collectionOfScoreButtons.index(of: sender) {
handleScoreValue(index: index)
}
}
Finally you can get scoreKey as rawValue of case for certain index in allCases array
func handleScoreValue(index: Int) {
let scoreKey = Score.allCases[index].rawValue
dictionary[scoreKey, default: 0] += 1
}
Why not just use an enum directly ?
enum Constants: String, CaseIterable {
case scoreA = "score_a"
case scoreB = "score_b"
case scoreC = "score_c"
case scoreD = "score_d"
}
So you can loop through your enum cases like
Constants.allCases[anyIndex].rawValue

How can i add an object, boolean and long value into an array in Kotlin?

I have this method
private fun checkRoomIdAndFindCinemaAndCheckIfRoomExists(paramRoomId: String?, paramCinemaId: String?, roomExists: Boolean?) : Array<Any> {
val roomId = ValidationHandler.validateId(paramRoomId, "room id")
val cinema = cinemaService.getCinemaById(paramCinemaId)
val roomExists = roomRepository.existsByIdAndCinemaId(roomId, paramCinemaId!!.toLong())
return arrayOf(roomId, cinema, roomExists)
}
What i want to do here is add roomId as Long , cinema as object and roomExists as boolean into an array, and return type should be the array. How can i do that?
Later i want to access these from another method.
I suggest to use idiomatic Kotlin code instead of what was suggested already. When you want to return multiple values from a function, you should utilize data functions or existing classes like Pair or Triple if sufficient. In this case, Triple helps you:
private fun checkRoomIdAndFindCinemaAndCheckIfRoomExists(
paramRoomId: String?,
paramCinemaId: String?,
roomExists: Boolean?
): Triple<Long, Any, Boolean.Companion> {
//TODO
return Triple(roomId, cinema, roomExists)
}
The good thing is that you can be sure about the types and don't have to cast anything from an unsafe Array<Any>. Furthermore, data classes let you make use of destructuring as shown here:
val (roomId, cinema, roomExists) =
checkRoomIdAndFindCinemaAndCheckIfRoomExists("id1", "id2", true)
You can call the method like this:
val array = checkRoomIdAndFindCinemaAndCheckIfRoomExists(paramRoomId, paramCinemaId, roomExists)
The array's inferred type is Array<Any>.
You can access the items of the array:
val roomId = array[0] as Long
val cinema = array[1] as YourObjectClass
val roomExists = array[2] as Boolean

convert value of type 'Result?' to type 'String'

I have problems to cast my array of type 'result' to an array of string. This is what I already tried:
EDIT:
I need the information as String type since I want to use the URL as image source.
swift4
let message = try? JSONDecoder().decode(Welcome.self, from: data)
let imageURLs = message?.children.attachment.results.filter({ $0.metadata.mediaType == "image/png" })
let latestImageURls = imageURLs?.prefix(2)
let latestImageURlsArray = Array(latestImageURls ?? [])
let image1 = self.view.viewWithTag(63) as! UIImageView
let image2 = self.view.viewWithTag(64) as! UIImageView
let image3 = self.view.viewWithTag(65) as! UIImageView
let url1 = URL(string: latestImageURlsArray[0]) // error:Cannot convert value of type 'Result' to expected argument type 'String
let url2 = URL(string: latestImageURlsArray[1]) // error:Cannot convert value of type 'Result' to expected argument type 'String
let url3 = URL(string: latestImageURlsArray[2]) // error:Cannot convert value of type 'Result' to expected argument type 'String
image1.kf.setImage(with: url1)
image2.kf.setImage(with: url2)
image3.kf.setImage(with: url3)
I think there is no such thing as [Array], I guess you're talking about Array<Result>. An array of Result object. What is the same as [Result].
If for some reason you want to create a new Array object from you ArraySlice, just call an initializer.
let resultsArray = Array(latestImageURls ?? [])
UPDATE
You're saying that you also need to convert your Result objects into String, but you disn't explain what is the Result object and how does it how is it related to the String. Does it contain it or it is a String? So I'll try to assume.
If you want to cast you objects into String, you can do it like that
let latestImageURlsArray = resultsArray.compactMap { $0 as? String }
If you want to extract your strings from results if they have it, (let's say that it's stored at imageURL parameter) you can do it like that
let latestImageURlsArray = resultsArray.compactMap { $0.imageURL }
After that, latestImageURlsArray will be an [String].
If the relation is completely different and more complicated, please add more details about the Result class, so I could make my answer more specific.
You're not doing any "casting", you're just saying "I expected a [Array]". You're not doing anything to make that be the case. In any case, that's not even valid, because Array isn't a valid type.
As you see, prefix returns an ArraySlice<T>, which provides a lightweight view into the memory of Array<T>, without copying any elements.
In general, the way you convert an ArraySlice of a given type to an Array of that type is to use the Array initializer:
struct Thing {
}
let things = [Thing]()
let sliceOfArrayOfThings = things.prefix(2)
let arrayOfThings = Array(sliceOfArrayOfThings)
In your case your Array is actually an Optional array, so you have to take some extra steps to deal with the optionality, as described by Yury in his answer:
let things: [Thing]? = []
let sliceOfArrayOfThings = things?.prefix(2)
let arrayOfThings = Array(sliceOfArrayOfThings ?? [])

Swift Can't access Single object array

I am trying to access data from a json file. The problem is that some of the values are NSSingleObjectArrays (Arrays with only item) which I can't turn into strings.
class CarObject {
var pictureURL: String!
var carURL: String!
var carPrice: String!
required init(json: [String: AnyObject]) {
pictureURL = json["galleryURL"] as! String
carURL = json["viewItemURL"] as! String
carPrice = json["currentPrice"] as! String
}
}
I get the following error message:
Could not cast value of type '__NSSingleObjectArrayI' (0x10a2ec548) to 'NSString' (0x109729440).
I tried to access them like this:
"json["galleryURL"][0] as String!"
but I get the following error:
Type 'Any?' has no subscript members
The values look like this:
galleryURL = ("one value");
Do you guys know a way how to access them easily?
Thanks!
Just cast things to the appropriate types first. It sounds like your values are arrays containing a single string, so something like this:
var pictureURL: URL
required init?(json: [String: AnyObject]) {
guard let pictureURLString = (json["galleryURL"] as? [String])?.first,
let pictureURL = URLComponents(string: pictureURLString)?.url else {
return nil
}
self.pictureURL = pictureURL
}
Also, you may want to reconsider the types you're using for your properties. The pictureURL and carURL properties are URLs, so they make more sense typed as URL. The carPrice property is likely numeric, so it makes more sense as a Double.

Resources