How to unwrap NSMutableDictionary.allkeys in optional String Array - ios

I am trying to get all the key values of NSMutableDictionary as String Array. I am using this myNSMutableDictionary.allkeys to get the values as an Array but I cannot find a way to unwrap the key values.
This is what I have tried so far:
for (key, _) in NSMutableDictionary {
println("THIS IS MY NEW KEY\(key)")
}
And I tried this
var myArray:NSArray = myNSMutableDictionary.allKeys
var string:NSString? = uniqueIDArray[0] as? NSString
println("This is unwraped value\(string!)")
And this
var myArray:Array = myNSMutableDictionary.allKeys
println("This is unwraped value\(myArray[0])")
I keep getting the value as Optional("kMSZgoTmiX") instead of kMSZgoTmiX which is the key value I need
Thank you for all your help!

So you've got a dictionary with values that are strings (and keys that are something, assume String):
var dictionaryOfStringValues : [String:String] = /* your dictionary */
And you want to iterate over the contents:
for (key, val) in dictionaryOfStringValues {
// use key and val
}
If you just want the values in a way you can easily iterate over:
var theValues = dictionaryOfStringValues.values
If you insist that theValues be an Array:
var theValuesAsAnArray = Array(dictionaryOfStringValues.values)
If you are starting with an NSMutableDictionary, then convert it at the point where it FIRST ENTERS your Swift code into a Swift Dictionary. Use an as variant to do that. After that, pure Swift.
Like this:
7> for (key, value) in ["a":1, "b":2] {
8. println (key)
9. println (value)
10. }
b
2
a
1

let myNSMutableDictionary = NSMutableDictionary()
myNSMutableDictionary["myKey1"] = 5
myNSMutableDictionary["myKey2"] = 10
myNSMutableDictionary["myKey3"] = 15
let myKeysArrayUnsorted = myNSMutableDictionary.allKeys as [String]
let myValuesArrayUnsorted = myNSMutableDictionary.allValues as [Int]
let keyString = myKeysArrayUnsorted[0] // "myKey2"
let keyValue = myNSMutableDictionary[keyString] as Int // 10
println("This is my first unsorted key \(keyString) = \(keyValue)")
let myKeysArraySorted = (myNSMutableDictionary.allKeys as [String]).sorted(<)
for key in myKeysArraySorted {
println(myNSMutableDictionary[key]!) // 5 10 15
}

Related

create a dictonary with for loop in swift

I just want to create a dictionary with the help of for loop
sample code :
var counter: Int = 1;
var pageCountDict = [String:Any]();
for filterCount in counter..<6
{
if let count = "page_\(filterCount)_vtime" as? String
{
pageCountDict = [count: timeInterval_Int];
}
}
print(pageCountDict);
This print command give me only last value of forloop
I just want all the value of this variable pageCountDict in a dictonary
The way to assign to a dictionary is first use the subscript and assign the value to it:
pageCountDict[YourKey] = YourValue
Also, you can see many examples and explanations in Apple documentation regarding dictionaries.
With each loop, you are replacing the dictionary with one that contains only one element. What you want to do is this :
pageCountDict[count] = timeInterval_Int
Also, you shouldn't need the as? String part. This should be sufficient :
for filterCount in counter..<6
{
pageCountDict[count] = "page_\(filterCount)_vtime"
}
var pageCountDict = [String:Any]()
You can add values to this dictionary by merging previous contents and new data as follows...
let counter: Int = 1
var pageCountDict = [String:Any]()
for filterCount in counter..<6
{
let value = 9
let count = "page_\(filterCount)_vtime" //'if' is not needed as it is always true
pageCountDict.merge([count: timeInterval_Int], uniquingKeysWith:{ (key, value) -> Any in
//assign value for similar key
timeInterval_Int
})
}
print(pageCountDict)`

Sorting array of dictionaries by value after for loop?

I've seen a lot of answers to similar questions but none of the methods have worked so far.
if let users = snapshot.value!["users"] as? Dictionary<String,AnyObject> {
each.users = Int(users.count)
var pointsArray = [Dictionary<String,Int>]()
for (key, value) in users {
let uid = key
let points = value["points"] as! Int
pointsArray.append([uid : points])
}
I'm then needing to sort pointsArray by the "points", sort it from high to low, grab the 0th (highest) element, then grab the uid to use.
I've tried:
var myArr = Array(pointsArray.keys)
var sortedKeys = sort(myArr) {
var obj1 = dict[$0] // get ob associated w/ key 1
var obj2 = dict[$1] // get ob associated w/ key 2
return obj1 > obj2
}
This gives me
Value of type [ Dictionary <String,Int>] has no member keys.
I guess that's cause I'm trying to run the sort on my array of dicts vs the dicts themselves? How do I switch this up to get into the actual dictionaries vs. running the sort on the array?
Right - you're not properly accessing the keys of the dictionaries.
Here's a working code:
var pointsArray = [Dictionary<String, Int>]()
pointsArray.append(["1" : 10])
pointsArray.append(["2" : 45])
pointsArray.append(["3" : 30])
// sort by points
let sorted = pointsArray.sort({ $0.first!.1 > $1.first!.1 })
print(sorted) // [["2": 45], ["3": 30], ["1": 10]]
Array(pointsArray.keys) - this doesn't work, because pointsArray is an array, therefore it doesn't have keys property. The contents of pointsArray are dictionaries and they have keys. So you can access the keys of the first dictionary like this: pointsArray[0].keys

How do I create a dictionary from an array of objects in swift 2.1?

I have an array of type "drugList", and they are derived from a struct "DrugsLibrary":
struct DrugsLibrary {
var drugName = ""
var drugCategory = ""
var drugSubCategory = ""
}
var drugList = [DrugsLibrary]()
//This is the dictionary i'm trying to build:
var dictionary = ["": [""," "]]
My data model is initialized using this function:
func createDrugsList() {
var drug1 = DrugsLibrary()
drug1.drugName = "drug1"
drug1.drugCategory = "Antibiotics"
drug1.drugSubCategory = "Penicillins"
self.drugList.append(drug1)
var drug2 = DrugsLibrary()
drug2.drugName = "drug2"
drug2.drugCategory = "Antibiotics"
drug2.drugSubCategory = "Penicillins"
self.drugList.append(drug2)
var drug3 = DrugsLibrary()
drug3.drugName = "drug2"
drug3.drugCategory = "Antibiotics"
drug3.drugSubCategory = "Macrolides"
self.drugList.append(drug3)
}
my problem is that i'm trying to create a dictionary from the drugList where the key is the drugSubCategory and the value is the drug name. The value should be an array if there are several drugs in this subcategory
for example, the dictionary should look something like this for this example:
dictionary = [
"Penicillins": ["drug1","drug2"]
"Macrolides": ["drug3"]
]
I tried this method:
for item in drugList {
dictionary["\(item.drugSubCategory)"] = ["\(item.drugName)"]
}
this gave a dictionary like this, and it couldn't append drug2 to "Penicllins":
dictionary = [
"Penicillins": ["drug1"]
"Macrolides": ["drug3"]
]
So I tried to append the items into the dictionary using this method but it didn't append anything because there were no common items with the key "" in the data model:
for item in drugList {
names1[item1.drugSubCategory]?.append(item1.drugName)
}
Anyone knows a way to append drug2 to the dictionary?
I would appreciate any help or suggestion in this matter.
You need to create a new array containing the contents of the previous array plus the new item or a new array plus the new item, and assign this to your dictionary:
for item in drugList {
dictionary[item.drugSubCategory] = dictionary[item.drugSubCategory] ?? [] + [item.drugName]
}
You can use .map and .filter and Set to your advantage here. First you want an array of dictionary keys, but no duplicates (so use a set)
let categories = Set(drugList.map{$0.drugSubCategory})
Then you want to iterate over the unique categories and find every drug in that category and extract its name:
for category in categories {
let filteredByCategory = drugList.filter {$0.drugSubCategory == category}
let extractDrugNames = filteredByCategory.map{$0.drugName}
dictionary[category] = extractDrugNames
}
Removing the for loop, if more Swifty-ness is desired, is left as an exercise to the reader ;).
I have two unrelated observations:
1) Not sure if you meant it as an example or not, but you've initialized dictionary with empty strings. You'll have to remove those in the future unless you want an empty strings entry. You're better off initializing an empty dictionary with the correct types:
var dictionary = [String:[String]]()
2) You don't need to use self. to access an instance variable. Your code is simple enough that it's very obvious what the scope of dictionary is (see this great writeup on self from a Programmers's stack exchange post.
Copy this in your Playground, might help you understand the Dictionaries better:
import UIKit
var str = "Hello, playground"
struct DrugsLibrary {
var drugName = ""
var drugCategory = ""
var drugSubCategory = ""
}
var drugList = [DrugsLibrary]()
//This is the dictionary i'm trying to build:
var dictionary = ["":""]
func createDrugsList() {
var drug1 = DrugsLibrary()
drug1.drugName = "drug1"
drug1.drugCategory = "Antibiotics"
drug1.drugSubCategory = "Penicillins"
drugList.append(drug1)
var drug2 = DrugsLibrary()
drug2.drugName = "drug2"
drug2.drugCategory = "Antibiotics"
drug2.drugSubCategory = "Penicillins"
drugList.append(drug2)
var drug3 = DrugsLibrary()
drug3.drugName = "drug2"
drug3.drugCategory = "Antibiotics"
drug3.drugSubCategory = "Macrolides"
drugList.append(drug3)
}
createDrugsList()
print(drugList)
func addItemsToDict() {
for i in drugList {
dictionary["item \(i.drugSubCategory)"] = "\(i.drugName)"
}
}
addItemsToDict()
print(dictionary)

Sort value in dictionary that resides within an array

I have an Array: var messageArray = [AnyObject]() and in that Array there is a single tuple that contains Dictionaries with 10 key/value paires (9 of them not important for the sort): var messageDetailDict = [String: AnyObject]()
Getting and setting those values all work correctly, however now I want to sort the Array by 1 of the values (not keys) of the Dictionary.
Example -> The Array has a tuple containing several Dictionaries:
The key in the Dictionary (which is the first element in the Array) is: 'ReceivedAt' which has a value of 21-03-2015
The key in the Dictionary (which is the second element in the Array) is: 'ReceivedAt' which has a value of 20-03-2015
The key in the Dictionary (which is the third element in the Array) is: 'ReceivedAt' which has a value of 15-03-2015
Now the Array should be sorted so that the values of 'ReceivedAt' will be sorted from earliest date, to the last date.
Hope this makes sense, but it's a bit difficult to explain. Thanks!
EDIT >>>>>
This is the println(messageArray) output:
[(
{
ConversationId = "94cc96b5-d063-41a0-ae03-6d1a868836fb";
Data = "Hello World";
Id = "eeb5ac08-209f-4ef0-894a-72e77f01b80b";
NeedsPush = 0;
ReceivedAt = "/Date(1439920899537)/";
SendAt = "/Date(1436620515000)/";
Status = 0;
},
{
ConversationId = "94cc96b5-d063-41a0-ae03-6d1a868836fb";
Data = "Hello World";
Id = "86b8766d-e4b2-4ef6-9112-ba9193048d9d";
NeedsPush = 0;
ReceivedAt = "/Date(1439921562909)/";
SendAt = "/Date(1436620515000)/";
Status = 0;
}
)]
And the received date is converted to a string with the following method (I do think however this is not important, as it is a time interval, and therefore OK to sort):
func getTimeStampFromAPIValue(dateTimeReceived: String) -> String {
let newStartIndex = advance(dateTimeReceived.startIndex, 6)
let newEndIndex = advance(dateTimeReceived.endIndex, -2)
let substring = dateTimeReceived.substringWithRange(newStartIndex..<newEndIndex) // ell
let receivedAtValueInInteger = (substring as NSString).doubleValue
let receivedAtValueInDate = NSDate(timeIntervalSince1970:receivedAtValueInInteger/1000)
//format date
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd-MM-yy hh:mm"
var dateString = dateFormatter.stringFromDate(receivedAtValueInDate)
return dateString
}
Since the values of ReceivedAt are timestamps as strings you could apply the following algorithm:
var sortedArray = messageArray.sorted { (dict1, dict2) in
// Get the ReceivedAt value as strings
if let date1String = dict1["ReceivedAt"] as? String,
let date2String = dict2["ReceivedAt"] as? String {
// Compare the date strings to find the earlier of the two
return date1String.compare(date2String) == .OrderedAscending
}
// Couldn't parse the date, make an assumption about the order
return true
}
Try this, change OrderedAscending with OrderedDescending if need in inverse order
messageArray.sortInPlace {
($0["ReceivedAt"] as! NSDate).compare($1["ReceivedAt"] as! NSDate) == .OrderedAscending
}

How to append associative array elements in Swift

How do I create and append to an associative array in Swift? I would think it should be something like the following (note that some values are strings and others are numbers):
var myArray = []
var make = "chevy"
var year = 2008
var color = "red"
myArray.append("trackMake":make,"trackYear":year,"trackColor":color)
The goal is to be able to have an array full of results where I can make a call such as:
println(myArray[0]["trackMake"]) //and get chevy
println(myArray[0]["trackColor"]) //and get red
Simply like this:
myArray.append(["trackMake":make,"trackYear":year,"trackColor":color])
Add the brackets. This will make it a hash and append that to the array.
In such cases make (extensive) use of let:
let dict = ["trackMake":make,"trackYear":year,"trackColor":color]
myArray.append(dict)
The above assumes that your myArray has been declared as
var myArray = [[String:AnyObject]]()
so the compiler knows that it will take dictionary elements.
I accept above answer.It is good.Even you have given correct answer,I like to give simplest way.The following steps are useful,if you guys follow that.Also if someone new in swift and if they go through this,they can easily understand the steps.
STEP 1 : Declare and initialize the variables
var array = Array<AnyObject>()
var dict = Dictionary<String, AnyObject>()
var make = "chevy"
var year = 2008
var color = "red"
STEP 2 : Set the Dictionary(adding keys and Values)
dict["trackMake"] = make
dict["trackYear"] = year
dict["trackColor"] = color
println("the dict is-\(dict)")
STEP 3 : Append the Dictionary to Array
array.append(dict)
println("the array is-\(array)")
STEP 4 : Get Array values to variable(create the variable for getting value)
let getMakeValue = array[0]["trackMake"]
let getYearValue = array[0]["trackYear"]
let getColorValue = array[0]["trackColor"]
println("the getMakeValue is - \(getMakeValue)")
println("the getYearValue is - \(getYearValue)")
println("the getColorVlaue is - \(getColorValue)")
STEP 5: If you want to get values to string, do the following steps
var stringMakeValue:String = getMakeValue as String
var stringYearValue:String = ("\(getYearValue as Int)")
var stringColorValue:String = getColorValue as String
println("the stringMakeValue is - \(stringMakeValue)")
println("the stringYearValue is - \(stringYearValue)")
println("the stringColorValue is - \(stringColorValue)")
STEP 6 : Finally the total output values are
the dict is-[trackMake: chevy, trackColor: red, trackYear: 2008]
the array is-[{
trackColor = red;
trackMake = chevy;
trackYear = 2008;
}]
the getMakeValue is - Optional(chevy)
the getYearValue is - Optional(2008)
the getColorVlaue is - Optional(red)
the stringMakeValue is - chevy
the stringYearValue is - 2008
the stringColorValue is - red
Thank You
This sounds like you are wanting an array of objects that represent vehicles. You can either have an array of dictionaries or an array of vehicle objects.
Likely you will want to go with an object as Swift arrays and dictionaries must be typed. So your dictionary with string keys to values of differing types would end up having the type [String : Any] and you would be stuck casting back and forth. This would make your array of type [[String : Any ]].
Using an object you would just have an array of that type. Say your vehicle object's type is named Vehicle, that would make your array of type [Vehicle] and each array access would return an instance of that type.
If I want to try it with my own statement. Which also I want to extend my array with the data in my dictionary and print just the key from dictionary:
var myArray = ["Abdurrahman","Yomna"]
var myDic: [String: Any] = [
"ahmed": 23,
"amal": 33,
"fahdad": 88]
for index in 1...3 {
let dict: [String: Any] = [
"key": "new value"
]
// get existing items, or create new array if doesn't exist
var existingItems = myDic[myArray] as? [[String: Any]] ?? [[String: Any]]()
// append the item
existingItems.append(myArray)
// replace back into `data`
myDic[myArray] = existingItems
}

Resources