Like objective-C , how to write "valueForKey" in swift? - ios

NSDictionary dic;
NSMutableArray array;
//Objective-C Code.
array = [dic valueForKey:#"Table"]; //"Table" is key in dictionary
How to write same code in Swift?

There is no more valueForKey: in Swift, but there is a way to use map to achieve a similar, if not same, result.
If the objects in the collection are dictionaries:
let array = dic.map { $0["table"] as? String }
If the objects in the collection are objects:
let array = dic.map{ $0.table }
If you are using Objective-C collection types like NSDictionary in your example, then like others have said, you can still continue to use valueForKey:.
let array = dic.valueForKey("table")

You can try this
let array: AnyObject? = dic["Table"]

Simple eg.
(dicDetail.valueForKey("name") as! String)

You can try this
var dict=NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: NSErrorPointer.null()) as NSDictionary
var temp=dict["contactname"] as String
var tem=dict.valueForKey("contactname") as String

You will better get the idea of how you can deal with Dictionaries in Swift
let employees = json["employees"]! as [[String : AnyObject]]
Next step is to loop the employees array and print the firstName and lastName.
Keep in mind that we are looping an array of dictionaries. Meaning that in order to get the String values from firstName and lastName we need to unwrap the optionals first:
for employee in employees {
let firstName = employee["firstName"]! as String
let lastName = employee["lastName"]! as String
println("employee: \(firstName) \(lastName)")
}
Build, run and you should see:
employee: John Doe
employee: Anna Smith
employee: Peter Jones

Please check this code. It might help in what you need.
var dictData = Dictionary <String,Any>()
var arrDictData = Array<Any>()
// Will store value for key in dictionary.
func storeData ( strName: String , strAge: String ) {
dictData["name"]=strName
dictData["age"]=strAge
println("dictData: \(dictData)")
storeInArray(dictData)
}
// Will store value of dictionary in array.
func storeInArray ( dict : Any ) {
arrDictData.append(dict)
println("arrDictData: \(arrDictData)")
}
// Will return count of array.
func resultArray() -> Int {
println(arrDictData.count)
return arrDictData.count
}
// This function will return value in label.
func arrDictResult( dictKey: String, rowIndex: Int) -> String {
var dataTemp = arrDictData[rowIndex] as Dictionary <String,Any>
var val = dataTemp[dictKey] as String
return val
}

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)`

Filtering Arrays Containing Multiple Data Types in Swift3

I have an array like:-
var arrayData : Array<Dictionary<String, [BottleModel]>> = []
Bottle model :-
class BottleModel: NSObject {
var name : String
var price : Int
var reviews : Int
var category : String
var quantity : String
var id : String
var shopData : ShopModel
}
I want filtered array where price is > 2000
I tried let searchByInts = arrayData.filter({m in m.price < 200})
but getting below error:
Contextual closure
type '(Dictionary) -> Bool' expects 1 argument,
but 0 were used in closure body
How to filter such kind of array based on price
Working code:
let searchByInts = arrayData.filter { $0.values.contains { $0.contains { $0.price > 2000 } } }
By the way please write the following using literals:
var arrayData : [[String : [BottleModel]]] = []
Still no idea if that is what you actually want because your goal is very unclear. You have an array of dictionaries of arrays which actually contain the values you want to filter out. If a BottleModel costs more than 2000 do you want to keep the entire array it is contained in and the dictionary that array is in? You might want to map the entire data into one flat array before or after filtering.
Alternative using flatMap:
let flat = arrayData.flatMap { $0.values.flatMap { $0 } }
let searchByInts2 = flat.filter { $0.price < 200 } // or some other criteria

Cannot add an append an array into a dictionary that has an empty array

I have a Profile Data singleton class as follows.
I am trying to store data into an empty array in a dictionary .
After appending data to the array also the count of the array is 0.
class ProfileData{
static let sharedInstance = ProfileData()
var artistProfileDict = [String : Profile]()
var loggedInUserProfile = Profile(artistName: "John Smith", artistDescription: "Admiral of New England, English soldier, explorer, and author.", totalLikes: "174", totalViews: "200", totalFollowing: "100",totalFollowers:"50",imageUrl:"image_singer", feeds:[] )
private init() {
getProfilesDictionary()
}
func getProfilesDictionary()->[String: Profile]{
artistProfileDict["John Smith"] = loggedInUserProfile
return artistProfileDict
}
func add(array: Feed, artistName: String) {
artistProfileDict[artistName]!.feeds.append(array)
}
}
In another view Controller I am trying to add an array to the empty array in the dictionary as follows
let newFeed = Feed(profilePicture: "image",artistName: "New",
videoUrl: "url",videoTitle:"New", videoViews: "160",likes:
"200",shoutouts: "200",comments: [],votes: "50", dateCreated: Date(),
userActivity :"This user liked your video")
ProfileData.sharedInstance.add(array: newFeed,artistName:"John Smith")
After appending the array to the empty array in the dictionary I still get the count of the array as 0.
I am not able to figure out the problem here. Any help will appreciated . Thank you.
Profile class
struct Profile {
var artistName: String
var artistDescription: String
var totalLikes: String
var totalViews: String
var totalFollowing: String
var totalFollowers: String
var imageUrl: String
var feeds : [Feed]
init(artistName: String,artistDescription:String,totalLikes:String,totalViews:String,totalFollowing:String,totalFollowers:String,imageUrl:String, feeds:[Feed]) {
self.artistName = artistName
self.artistDescription = artistDescription
self.totalLikes = totalLikes
self.totalViews = totalViews
self.totalFollowing = totalFollowing
self.totalFollowers = totalFollowers
self.imageUrl = imageUrl
self.feeds = feeds
}
}
It's working fine
ProfileData.sharedInstance.add(array: newFeed,artistName:"John Smith")
ProfileData.sharedInstance.artistProfileDict["John Smith"]?.feeds.count // 1
Probably you are using wrong class ArtistProfileData instead of ProfileData.

How to remove duplicates values and create a table view section in Swift?

Thanks for the help guys, I have a dictionary with an array of dictionary.
My objective is to sort out an array that is read from a plist file, out of one inner dictionary value. The values are String type and returns an array with duplicate values. This returned array has a total count of 30 values (elements) that can be categorized in 6 values. I need to somehow create an array out these 6 values so I can use it on my tableView Data Source, numberOfSectionsInTableView:
I looked into map() and filter() but could not walk away with any solution. My codes are;
// setupLoading called from viewDidLoad()
func setupLoading() {
let path = NSBundle.mainBundle
let bundlePath = path.pathForResource("KempfRef", ofType: "plist")
let dict: NSDictionary? = NSDictionary(contentsOfFile: bundlePath!)
let plistArray: NSArray = dict!["KempfRef"] as NSArray
for innerDict in plistArray as Array {
let kempf: KempfFiber = KempfFiber() // Model
kempf.name = innerDict["Name"] as String
kempf.detail = innerDict["Detail"] as String
kempf.imageName = innerDict["ImageName"] as String
kempf.specGrav = innerDict["SpecGrav"] as String
kempf.toughness = innerDict["Toughness"] as String
kempf.pdfFile = innerDict["PDF"] as String
//println("DESCRIPTION: \(kempf.description())")
var theType = innerDict["Type"] as String
var kempfTypes = [String](arrayLiteral: theType)
println("theType")
}
// Here are the println of theType
The Types are:
BERKempf
BERKempf
BERKempf
BERKempf
CHRYBERKempf
CHRYBERKempf
CHRYBERKempf
CORUNKempf
CORUNKempf
CORUNKempf
CORUNKempf
GARNKempf
GARNKempf
GARNKempf
GARNKempf
GARNKempf
GARNKempf
GARNKempf
OTHERKempf
OTHERKempf
OTHERKempf
OTHERKempf
OTHERKempf
OTHERKempf
OTHERKempf
SPINEKempf
SPINEKempf
SPINEKempf
SPINEKempf
Thanks guys
I would create another dictionary with a string key (which will be your type) and an array of KempfFiber as the values. Then when you get a type you retrieve the array from the dictionary. If it is nil then create a new array, add the kempf object to it, otherwise just add the kempf object to the existing array. You can then get the keys as an array for your sections.
Something like this (where kempfData and sectionKeys are properties of your current class -
self.kempfData=[String:[KempfFiber]]
for innerDict in plistArray as Array {
let kempf: KempfFiber = KempfFiber() // Model
kempf.name = innerDict["Name"] as String
kempf.detail = innerDict["Detail"] as String
kempf.imageName = innerDict["ImageName"] as String
kempf.specGrav = innerDict["SpecGrav"] as String
kempf.toughness = innerDict["Toughness"] as String
kempf.pdfFile = innerDict["PDF"] as String
var theType = innerDict["Type"] as String
var kempfArray=self.kempfData[theType]
if (kempfArray ==nil) {
kempfArray =[Kempf]()
}
kempfArray!.append(kempf)
self.kempfData[theType]= kempfArray
}
self.sectionKeys=Array(self.kempfData.keys)
Now you can return sectionKeys.count as your section count.
Your numberOfRowsInSection will be
let sectionData=self.kempfData[self.sectionKeys[indexPath.section]]
if (sectionData != nil) {
return sectionData!.count
}
else {
return 0
}
Similarly, in you cellForRowAtIndexPath you can access the data using
let sectionData=self.kempfData[self.sectionKeys[indexPath.section]]
if (sectionData != nil) {
let kempf=sectionData[indexPath.row]
// Configure your cell...
}
else {
// Something bad happened
}
You may want to sort the self.sectionKeys array after you create it, so that your sections are in alphabetical order.

How to unwrap NSMutableDictionary.allkeys in optional String Array

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
}

Resources