sort array of anyobject Swift 3 - ios

I am trying to sort an array of anyobject, but not able to do it.I get some data from Parse database in AnyObject format. As per below data, I want to sort this AnyObject array by "NAME". Below is my code -
let sortedArray = (myArray as! [AnyObject]).sorted(by: { (dictOne, dictTwo) -> Bool in
let d1 = dictOne["NAME"]! as AnyObject; // this line gives error "Ambiguous use of subscript"
let d2 = dictTwo["NAME"]! as AnyObject; // this line gives error "Ambiguous use of subscript"
return d1 < d2
})
myArray looks like this -
{
LINK = "www.xxx.com";
MENU = Role;
"MENU_ID" = 1;
NAME = "A Name";
SUBMENU = "XXX";
"Training_ID" = 2;
},
{
LINK = "www.xyz.com";
MENU = Role;
"MENU_ID" = 2;
NAME = "B name";
SUBMENU = "jhjh";
"Training_ID" = 6;
},
{
LINK = "www.hhh.com";
MENU = Role;
"MENU_ID" = 3;
NAME = "T name";
SUBMENU = "kasha";
"Training_ID" = 7;
},
{
LINK = "www.kadjk.com";
MENU = Role;
"MENU_ID" = 5;
NAME = "V name";
SUBMENU = "ksdj";
"Training_ID" = 1;
},
{
LINK = "www.ggg.com";
MENU = Role;
"MENU_ID" = 4;
NAME = "K name";
SUBMENU = "idiot";
"Training_ID" = 8;
},
{
LINK = "www.kkk.com";
MENU = Role;
"MENU_ID" = 6;
NAME = "s name";
SUBMENU = "BOM/ABOM/BSM";
"Training_ID" = 12;
}
Any help would be much appreciated. Thanks!

It's not [AnyObject] (array of I-have-no-idea), it's array of dictionaries [[String:Any]]. Be more specific, this resolves the error.
In Swift 3 the compiler must know the specific type of all subscripted objects.
let sortedArray = (myArray as! [[String:Any]]).sorted(by: { (dictOne, dictTwo) -> Bool in
let d1 = dictOne["NAME"]! as String
let d2 = dictTwo["NAME"]! as String
return d1 < d2
})

Why are converting array to [AnyObject] instead of that convert the array to the [[String:Any]] means Array of Dictionary and tell the compiler that array contains Dictionary as objects.
if let array = myArray as? [[String:Any]] {
let sortedArray = array.sorted(by: { $0["NAME"] as! String < $1["NAME"] as! String })
}
Note: As of you are having NAME key with String value in your each dictionaries of array I have force wrapped it with the subscript.

You can use below function if you want
//function to sort requests
func sortRequests(dataToSort: [[String:Any]]) -> [[String:Any]] {
print("i am sorting the requests...")
var returnData = [[String:Any]]()
returnData = dataToSort
returnData.sort{
let created_date0 = $0["date"] as? Double ?? 0.0
let created_date1 = $1["date"] as? Double ?? 0.0
return created_date0 > created_date1
}
return returnData
}

Related

Parsing my SWIFT Dictionary

I am querying a JSON database of zombies and it returns them as a Dictionary. I don't know how to mutate it with SWIFT 3
Here's the query::
func getZombieAttackGroupFromDatabase () {
ref?.child("Attacker Group").child((self.userParty?.leadID)!).observeSingleEvent(of: .value, with: { (snapshot) in
// Get data
print("PULLING DATA")
if let value = snapshot.value as? NSDictionary{
// break data into an Array of Zombie Structs
// print(value)
for zombieID in value.allKeys {
print(value[zombieID])
let thisZombieID = zombieID
let thisZombieGroup = value[zombieID]["Group"]
}
} else {
}
// ...
}) { (error) in
print(error.localizedDescription)
}
}
this part: let thisZombieGroup = value[zombieID]["Group"] isn't being recognized. How do I access group? If i get that, i can modify to the other components.
Here's the return :
{
"-KrNSmv64Ia32g5nw1L9" = {
Group = 15;
Health = 250;
"Is Undead" = true;
Location = 1;
Number = 0;
};
"-KrNSmv64Ia32g5nw1LA" = {
Group = 11;
Health = 250;
"Is Undead" = true;
Location = 5;
Number = 1;
};
"-KrNSmv64Ia32g5nw1LB" = {
Group = 2;
Health = 250;
"Is Undead" = true;
Location = 3;
Number = 2;
};
"-KrNSmv776r9eO6t7CY0" = {
Group = 14;
Health = 250;
"Is Undead" = true;
Location = 0;
Number = 3;
};
"-KrNSmv776r9eO6t7CY1" = {
Group = 0;
Health = 250;
"Is Undead" = true;
Location = 4;
Number = 4;
};
}
As you can see, each of the Structs has a parent that is an automatically generated ID. I don't know how to access it.
How can I access each element from item 1? I need the parent auto-key "-KrNSmv64Ia32g5nw1L9" and each child value.
"-KrNSmv64Ia32g5nw1L9" = {
Group = 15;
Health = 250;
"Is Undead" = true;
Location = 1;
Number = 0;
Cast value to a proper Swift dictionary, not NSDictionary.
if let value = snapshot.value as? [String:Any].
You just have to iterate through the keys of the dictionaries, get the embedded dictionary using the key value and then parse the "zombie data".
for key in value.keys {
if let zombieData = value[key] as? [String:Any] {
zombieData
if let group = zombieData["Group"] as? Int, let health = zombieData["Health"] as? Int, let isUndead = zombieData["Is Undead"] as? Bool, let location = zombieData["Location"] as? Int, let number = zombieData["Number"] as? Int {
//use the parsed data
}
}
}
Try this:
for zombieID in value.allKeys {
print(value[zombieID])
let thisZombieID = zombieID
if let zombieValues = value[zombieID] as? [String:Any] {
let thisZombieGroup = zombieValues["Group"] as? Int
}
}
First, Thank you so much to Woof and David. It was a combination of both of your ideas that got it to work.
func getZombieAttackGroupFromDatabase () {
ref?.child("Attacker Group").child((self.userParty?.leadID)!).observeSingleEvent(of: .value, with: { (snapshot) in
// Get data
print("PULLING DATA")
if let value = snapshot.value as? [String:Any]{
// break data into an Array of Zombie Structs
for zombieID in value.keys {
let thisZombieID = zombieID
print(thisZombieID)
let zombieValues = value[zombieID] as? [String:Any]
let thisZombieGroup = zombieValues?["Group"] as! String
print(thisZombieGroup)
}
} else {
}
// ...
}) { (error) in
print(error.localizedDescription)
}
}
}

Swift 3: Accessing nested dictionary from returns nil?

I'm having a problem trying to access a nested Dictionary, which seems to return nil.
Here's the output my info of type Dictionary<String, Any>:
info = ["list_order": 1, "name": Some Text, "id": 1, "menu_items": {
1 = {
"food_name" = "String";
"food_picture" = "link";
"food_price" = "2.00";
};
2 = {
"food_name" = "String";
"food_picture" = "link";
"food_price" = "5.00";
id = 2;
};
}]
The output of info["menu_items"]:
info["menu_items"] = {
1 = {
"food_name" = "String";
"food_picture" = "link";
"food_price" = "2.00";
id = 1;
};
2 = {
"food_name" = "String";
"food_picture" = "link";
"food_price" = "5.00";
id = 2;
};
}
However, the following assigning produces a nil in test:
let test = info["menu_items"] as? Dictionary<Int, Any>
Is there something not obvious or am I not understanding basic fundamentals?
If your key is not Int type then most probably it is of String type, try once using [String: Any].
if let menuItems = info["menu_items"] as? [String: Any] {
print(menuItems)
}

Get the index out of AnyObject list of items IOS

parsed is an NsDictionary and I am pulling the balances out of it via
if let findbalances: AnyObject = parsed["balances"]
which gives me a list of balances in AnyObject format
(
{
"available_amount" = 133519;
currency = AUD;
},
{
"available_amount" = 7854;
currency = CAD;
},
{
"available_amount" = 88581;
currency = EUR;
},
{
"available_amount" = 0;
currency = GBP;
},
{
"available_amount" = 63618;
currency = INR;
},
{
"available_amount" = 375;
currency = NZD;
},
{
"available_amount" = 0;
currency = TRY;
},
{
"available_amount" = 2918958;
currency = USD;
}
)
I know that
let whatCurrency = (findbalances[7]["currency"] as! String)
=USD But how do I find that value [7] if the amount of objects changes?
I want to match on USD
I tried
let defaultcurr = "USD"
let findUSD = findbalances.indexOfObject(defaultcurr)
but that gave me 9223372036854775807
How do I just find 7
9223372036854775807 is NSNotFound.
You can use a closure as argument of indexOf
let defaultcurr = "USD"
let findUSDIndex = findbalances.indexOf { ($0["currency"] as! String) == defaultcurr }
Or you can filter the entire row
let findUSD = findbalances.filter { ($0["currency"] as! String) == defaultcurr }.first
indexOfObject seems to be using NSArray. Don't do that. Use Swift native Array and cast your collection object to [[String:AnyObject]] :
if let findbalances = parsed["balances"] as? [[String:AnyObject]] { ...

Get index of object from array of dictionary with key value

I have one array with dictionary.
Now i want to get index number of object with particular key value.
Like key = "xyz" and value = "abc".
I need index of object having above matching in dictionary.
{
Id = 20085;
IsNew = 1;
Title = Circular;
},
{
Id = 20088;
IsNew = 0;
Title = Query;
},
{
Id = 20099;
IsNew = 1;
Title = Blog;
},
{
Id = 20104;
IsNew = 1;
Title = News;
},
{
Id = 20172;
IsNew = 1;
Title = AssignTask;
},
{
Id = 20183;
IsNew = 1;
Title = Gallery;
},
{
Id = 20204;
IsNew = 1;
Title = Poll;
},
{
Id = 20093;
IsNew = 1;
Title = Assignment;
},
{
Id = 20209;
IsNew = 1;
Title = Activity;
},
{
Id = 20130;
IsNew = 1;
Title = Behaviour;
},
{
Id = 20180;
IsNew = 1;
Title = Result;
}
now i need index of object with having key = "Title" and value = "result"
You can use indexOf(_:) for this:
let index = array.indexOf{ $0["key"] == value }
In Swift 3.0, it's been renamed to index(Where:):
let index = array.index{ $0["key"] == value }
You can see this in action here.
Here is what you should be doing after using a json parser
let array:NSArray = [
[
"Id": 20130,
"IsNew": 1,
"Title":"Behaviour"
],
[
"Id": 20180,
"IsNew": 1,
"Title":"Result"
]]
let k = array as Array
let index = k.indexOf {
if let dic = $0 as? Dictionary<String,AnyObject> {
if let value = dic["Title"] as? String
where value == "Result"{
return true
}
}
return false
}
print(index) // index
I'd start with mapping the id values to an array, then getting the index of the id you're looking for.
func getIndexOf(itemID: Int) -> Int {
//Map out all the ids from the array of dictionaries into an array of Integers
let keysArray = dictionaries.map { (dictionary) -> Int in
return dictionary.value(forKey: "Id")
}
//Find the index of the id you passed to the functions
return keysArray.index(of: itemID)
}
other mainstream way to do this
func getIndex(of key: String, for value: String, in dictionary : [[String: Any]]) -> Int{
var count = 0
for dictElement in dictionary{
if dictElement.keys.contains(key) && dictElement[key] as! String == value{
return count
}
else{
count = count + 1
}
}
return -1
}
var sampleDict : [[String:Any]] = [
[
"Id" : 20130,
"IsNew" : 1,
"Title" : "Behaviour"
],
[
"Id" : 20130,
"IsNew" : 1,
"Title" : "Result"
],
]
let index = getIndex(of: "Title", for: "Result", in: sampleDict)
print(index)
This will print 1.
This answer is for the Swift 5.2 and above versions.
arr.append(["Title":titleName,"ID":1,"Result":true])
arr.append(["Title":titleName,"ID":2,"Result":true])
arr.append(["Title":titleName,"ID":3,"Result":true])
arr.append(["Title":titleName,"ID":4,"Result":true])
This is an array of dictionary format. And if you want to find an index of an object where ID == 3
func findIndex(Id : Int ) -> Int? {
guard let index = arr.firstIndex(where: {
if let dic = $0 as? Dictionary<String,AnyObject> {
if let value = dic["ID"] as? Int, value == Id {
return true
}
}
return false
}) else { return nil }
return index
}
let myIndex = findIndex(3)
self.arr.insert( ["Title":titleName,"ID":10,"Result":true]) at: myIndex)

How to check value exists in array of dictionary as value?

{
QueueId = 27;
SongId = 38;
artWorkURL = "<null>";
duration = 58258;
"stream_url" = "https://api.soundcloud.com/tracks/233301835/stream";
title = Magenta;
trackID = 233301835;
userAvatar = "https://i1.sndcdn.com/avatars-000188204071-llusgk-large.jpg";
userName = Agiv;
},
{
QueueId = 27;
SongId = 39;
artWorkURL = "<null>";
duration = 79000;
"stream_url" = "https://api.soundcloud.com/tracks/233301833/stream";
title = Nino;
trackID = 233301833;
userAvatar = "https://i1.sndcdn.com/avatars-000157591669-eva3mg-large.jpg";
userName = "SWR Umwelt und Ern\U00e4hrung";
}
My array of dictionary format is as above and multiple tracks i want to check 27 is already there or not ?
You can do this with the filter function
let queueID27Exists = !array.filter({$0["QueueId"] as? Int == 27}).isEmpty
This answer is for your previous JSON object!
if let results : NSDictionary = post.objectForKey("data") as? NSDictionary {
let array:NSArray = (results.valueForKey("track") as! NSArray)
if "25" == array[0].valueForKey("trackID") as? String {
NSLog("YES")
} else {
NSLog("NO")
}
}
var found = false
for (_, data) in post {
let track = data["track"]
if track["trackID"] == "25" {
found = true
}

Resources