I have an data model object with several properties. I have a dynamic array that will sometimes have some but not all of the object properties inside of it.
How do I safely check if the array as anything at it's index
DataModel
class Order{
var item0:String?
var item1:String?
var item2:String?
}
Array:
var myArray = [String]()
The guard statements are where I'm having issues checking to see if there are elements inside the array at different indexes.
Btw the array will never have more then 3 elements inside of it.
let order = Order()
order.item0 = "hat"
order.item1 = "sneakers"
myArray.append(order.item0)
myArray.append(order.item1)
//sometimes there may or may not be item2
let placedOrder = Order
//These guard statements aren't working
guard case let placedOrder.item0 = myArray[0] else {return}
guard case let placedOrder.item1 = myArray[1] else {return}
//There isn't anything at myArray[2] but I need to safely check anyway
guard case let placedOrder.item2 = myArray[2] else {return}
1st The array should hold the data model type and not it's properties:
var orders = [Order]()
//changed the array's name from myArray to orders instead
2nd Add the data model object to the array:
let orderOne = Order()
orders.append(orderOne)
3rd loop through the array, check that the element's properties aren't nil:
for order in orders{
if order.item0 != nil{
//do something with order.item0
}
if order.item1 != nil{
//do something with order.item1
}
if order.item2 != nil{
//do something with order.item2
}
}
Related
I realise that I am missing something simple but as a Swift newbie I am going around in circles & would appreciate a pointer as to what I am doing wrong?!
I have a Core Data Entity called "Numbers" with an attribute (Int16) called "userNumbers". I am fetching the results like:
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Numbers")
//request.predicate = NSPredicate(format: "age = %#", "12")
request.returnsObjectsAsFaults = false
do {
let result = try context.fetch(request)
for data in result as! [NSManagedObject] {
print("\(data.value(forKey: "userNumbers") as! Int16)")
}
} catch {
print("Failed")
}
The result in my console is:
12
13
18
19
21
I need to know how to make this a comma separated list so I can use it in an array. Essentially I need the return to be: 12,13,18,19,21
Everything I try seems to be wrong!
First of all create a more specific fetch request to get a distinct result type
let request = NSFetchRequest<Numbers>(entityName: "Numbers")
A comma separated list is not possible because the type of userNumbers is numeric.
You can map the result to an array of Int16 with
do {
let result = try context.fetch(request) // the type is [Numbers]
let numberArray = result.map{$0.userNumbers}
print(numberArray)
}
I am getting a JSON from an API. So, I want to store a particular value with key SKU. So, what I did was:
var skuArr = [""]
{ (response, error) in
if (error != nil)
{
print("Error \(error.debugDescription)")
}
else
{
self.coinsArr = response.arrayObject as? Array<Dictionary<String, Any>>
for i in 0 ..< (self.coinsArr?.count)!
{
self.skuArr = [response[i]["sku"].rawValue as! String]
}
}
So, with this I am getting the array in skuArr, but when i is 0 I am getting ["a"], and when i is 1 I want it to be ["a","b"], but it gives ["b"] only and when the loop ends with only the last value and not with ["a","b","c","d"] which I want as the final result. How can I insert each of them in the Array?
First of all declare skuArr as empty string array.
var skuArr = [String]()
And this is Swift. There are better ways than ugly index based loops to extract data for example with map or compactMap
if let result = response.arrayObject as? Array<Dictionary<String, Any>> {
self.coinsArr = result
self.skuArr = result.compactMap{ $0["sku"] as? String }
}
And why is coinsArr declared as optional as you are going to force unwrap it anyway? It's highly recommended to use non-optional types as much as possible. Non-optionals can never cause a well-liked unexpected found nil crash
Don't use this:
self.skuArr = [response[i]["sku"].rawValue as! String]
As this will replace the previous value with new one.
Use .append to insert into array.
self.skuArr.append([response[i]["sku"].rawValue as! String])
EDIT
change your initialisation as below:
skuArr: [String] = []
for tempExportData in exportDataArray {
let tmpRegNO:NSString = (tempExportData as AnyObject).object(forKey: kRegisteredNo) as! NSString
print("tmpRegNO is",tmpRegNO)
var tmpNoArray:Array = [String]()
tmpNoArray.append(tmpRegNO as String)
print("Count is",tmpNoArray.count)
print("ARRAY is",tmpNoArray)
}
I am trying to add string value i.e tmpRegNO to the Array tmpNoArray.
In this I can able to add only one value to the array at a time.
How to add the next value to that array when it is looping for second time.
As already mentioned you have to declare the array before entering the loop.
Your code is very objectivecish. This is a swiftier version. Don't annotate types the compiler can infer and use key subscription rather than ugly casting to AnyObject and objectForKey:.
var tmpNoArray = [String]()
for tempExportData in exportDataArray {
let tmpRegNO = tempExportData[kRegisteredNo] as! String
print("tmpRegNO is",tmpRegNO)
tmpNoArray.append(tmpRegNO)
print("Count is",tmpNoArray.count)
print("ARRAY is",tmpNoArray)
}
You can even write the whole expression in one line:
let tmpNoArray = exportDataArray.flatMap { $0[kRegisteredNo] as? String }
You need move the tempNoArray initialization outside of your for in loop, if not the your array will be initialized once for every item in your exportDataArray remaining only the las item as consequence
You need something like this
var tmpNoArray:Array = [String]()
for tempExportData in exportDataArray{
if let tmpRegNO = tempExportData[kRegisteredNo] as? String
{
print("tmpRegNO is",tmpRegNO)
tmpNoArray.append(tmpRegNO as String)
print("Count is",tmpNoArray.count)
print("ARRAY is",tmpNoArray)
}
}
I've got a server response returning
(
{
agreementId = "token.virtual.4321";
city = AMSTERDAM;
displayCommonName = "bunch-of-alphanumeric";
displaySoftwareVersion = "qb2/ene/2.7.14";
houseNumber = 22;
postalCode = zip;
street = "";
}
)
how do I get the value of agreementId? response['agreementId'] is not working. i've tried some example code with .first but I cannot get it working.
Some extra information, I do a http call to a server with alamofire. I try to parse the json to a constant response:
let response = JSON as! NSDictionary
However that returns a error message
Could not cast value of type '__NSSingleObjectArrayI' (0x1083600) to 'NSDictionary' (0x108386c).
So now parse the json to an array, which seems to be working. The code above is what
let response = JSON as! NSArry
print(response)
spits out.
Now I only need to retrieve the value from the key "agreementId" and I have no clue how to do that.
In swift you need to use Swift's native type Array/[] and Dictionary/[:] instead of NSArray and NSDictionary, if you specify the type like above means more specific then the compiler won't complain. Also use optional wrapping with if let or guard let to prevent crash.
if let array = JSON as? [[String:Any]] {//Swift type array of dictionary
if let dic = array.first {
let agreementId = dic["agreementId"] as? String ?? "N/A"//Set default value instead N/A
print(agreementId)
//access the other key-value same way
}
}
Note: If you having more than one object in your array then you need to simply loop through the array to access each dictionary of array.
if let array = JSON as? [[String:Any]] {//Swift type array of dictionary
for dic in array {
let agreementId = dic["agreementId"] as? String ?? "N/A"//Set default value instead N/A
print(agreementId)
//access the other key-value same way
}
}
I am currently struggling with obtaining a value from an array inside an array of dictionaries. Basically I want to grab the first "[0]" from an array stored inside an array of dictionaries. This is basically what I have:
var array = [[String:Any]]()
var hobbies:[String] = []
var dict = [String:Any]()
viewDidLoad Code:
dict["Name"] = "Andreas"
hobbies.append("Football", "Programming")
dict["Hobbies"] = hobbies
array.append(dict)
/// - However, I can only display the name, with the following code:
var name = array[0]["Name"] as! String
But I want to be able to display the first value in the array stored with the name, as well. How is this possible?
And yes; I know there's other options for this approach, but these values are coming from Firebase (child paths) - but I just need to find a way to display the array inside the array of dictionaries.
Thanks in advance.
If you know "Hobbies" is a valid key and its dictionary value is an array of String, then you can directly access the first item in that array with:
let hobby = (array[0]["Hobbies"] as! [String])[0]
but this will crash if "Hobbies" isn't a valid key or if the value isn't [String].
A safer way to access the array would be:
if let hobbies = array[0]["Hobbies"] as? [String] {
print(hobbies[0])
}
If you use a model class/struct things get easier
Given this model struct
struct Person {
let name: String
var hobbies: [String]
}
And this dictionary
var persons = [String:Person]()
This is how you put a person into the dictionary
let andreas = Person(name: "Andreas", hobbies: ["Football", "Programming"])
persons[andreas.name] = Andreas
And this is how you do retrieve it
let aPerson = persons["Andreas"]