Reorder array of Dictionary By swift - ios

I'm working on ios app by swift!
An i need to display the data from the array of dictionary order by the price value.
How can i reorder this array
(
{
price = 269600;
userid = "facebook:851661711521620";
},
{
price = 294600;
userid = "facebook:851661711521620";
},
{
price = 1345600;
userid = "facebook:851661711521620";
},
{
price = 287600;
userid = "facebook:851661711521620";
},
{
price = 1344600;
userid = "facebook:851661711521620";
},
{
price = 1343600;
userid = "facebook:851661711521620";
},
{
price = 1333600;
userid = "facebook:851661711521620";
},
{
price = 1332600;
userid = "facebook:851661711521620";
},
{
price = 1322600;
userid = "facebook:851661711521620";
},
{
price = 322600;
userid = "facebook:851661711521620";
},
{
price = 302600;
userid = "facebook:851661711521620";
},
{
price = 300600;
userid = "facebook:851661711521620";
},
{
price = 291600;
userid = "facebook:851661711521620";
},
{
price = 282600;
userid = "facebook:851661711521620";
},
{
price = 299600;
userid = "facebook:851661711521620";
}
)
to be ordered by price from The highest to The lowest?
i need to display the data to be like this
Any ideas how can i do it Thanks!
Thanks!
Edited add some actual code.
self.currentBidDict = snapshot.value["current_bid_id"] as! NSDictionary
for(var i = 0;i <= self.currentBidDict.count - 1;i++){
self.currentBidDictReOrder.insertObject(self.currentBidDict.allValues[i], atIndex: 0)
println(self.currentBidDictReOrder)
}
Then after i printIn i got array above in the question.

There is a function, sort, that takes any sequence, and returns a sorted array. Since dictionaries are sequences of (key,value) pairs, you can pass the dictionary in to sort.
If what you pass in isn’t naturally sortable (i.e. the elements of the sequence are Comparable, which dictionaries aren’t), you need to also supply a closure telling sort how to order the elements. In your case, you want that closure to compare the value for a specific key in the dictionaries.
Finally, you want to sort by a value, but looking up a key in a dictionary returns an optional (because the key might not be there). But, this is fine! Because optionals have a < operator that works, so long as what the optional contains is comparable. Except, it looks like you’ve got a dictionary of Any or AnyObject (because you have both strings and integers in there), so you’ll have to covert them to something you can compare.
Put it all together and:
sorted(dict) { ($0["price"] as? Int) > ($1["price"] as? Int) }
You might want to tweak that as? a bit depending on what your dictionary actually contains. Also, I’d strongly suggest looking at creating a more strongly-typed struct and populating that with your data, rather than leaving it in dictionary form like this.

You can use the sort function in the following way:
var dict = [[
"price" : 1111,
"userid" : "facebook:851661711521620"
],
[
"price" : 12222,
"userid" : "facebook:851661711521620"
],
[
"price" : 144444,
"userid" : "facebook:851661711521620"
]]
// sort by price
dict.sort {
x, y in
let item1 = x["price"] as! Int
let item2 = y["price"] as! Int
return item1 > item2
}
And the output should be like this:
[[price: 144444, userid: facebook:851661711521620], [price: 12222, userid: facebook:851661711521620], [price: 1111, userid: facebook:851661711521620]]
I hope this help you.

Related

Filter the Dictionary With Array value

I have Array which contain ID like
var ID = ["782", "783", "784", "785", "786", "788", "789", "790", "791", "792", "793", "795", "805"]
And One Arr Of Dictionary like
Var arr2 = [["ID":"782","AmenitiesURL":"xyx.com"],["ID":"783","AmenitiesURL":"xybx.com"],["ID":"784","AmenitiesURL":"xyax.com"]]
Aslo see in image. Now I want to get the url of the ID.
Ex. if arr ID= 784 Then i want find that ID in the arr2 and get their url and append in New array,
In short Two array one is for ID and other for URL.
To get the URL of a specific id
let id = "784"
if let dict = arr2.first(where: { $0["ID", default:""] == id }), let urlString = dict["AmenitiesURL"] {
print(urlString)
}
You can get that working using the following approach:
let urls = ID.compactMap { (id) in
return arr2.first(where: {$0["ID"] == id})?["AmenitiesURL"]
}
Output:
print(urls) //["xyx.com", "xybx.com", "xyax.com"]
For all the ids in ID array, you'll get AmenitiesURL values from arr2 array.
Another approach. Though this one retains the structure of arr2
let filteredArray = arr2.filter { dict -> Bool in
for id in ID{
if dict["ID"] == id{
return true
}
}
return false
}

Applying filter and calculating Average on NSDictionary with JSON origin

I read some posts here and google about it, but still couldn't understand how to do a simple filter using the swift filter feature. I am new to Swift and functional programing, so forgive me if that is too basic.
I have the following JSON:
{
"-KjirKH7Bo7c5vq7ZH9N" = {
rank = 2;
placa = "xxx-0003";
uid = yNpL0uzI5LRj6etFGVgoWYEK2E52;
};
"-Kjiyi_i7FLl6dks6xKL" = {
rank = 5;
placa = "xxx-0003";
uid = yNpL0uzI5LRj6etFGVgoWYEK2E52;
};
}
I was able to create an array of the values with:
if let dict = snapshot.value as? NSDictionary{
let myArray = dict.map{$0.value} //array of values
}
Which creates this:
[{
rank = 5;
placa = "xxx-0003";
uid = yNpL0uzI5LRj6etFGVgoWYEK2E52;
}, {
rank = 2;
placa = "xxx-0003";
uid = yNpL0uzI5LRj6etFGVgoWYEK2E52;
}]
My goal now is:
Apply a filter to retrieve only items that the property "rank" is greater than 0.
After that I want to calculate the items rank average (in this example 2+5/2 = 3.5).
I have tried this:
myArray.filter{$0.rank > 0 }
But it fails with "Value of type 'Any' has no member 'rank'"
Any idea how I can filter this array?
I have tried with NSPredicate, but I am wondering if there is some way to take advantage of the native filter.
Looks like you have two issues:
myArray's items are of type Any and in reality they are dictionaries so you have to help compiler to understand that. Here is how to do it:
let myArray: [[String: Any]] = dict.map{ $0.value }
Because myArray contains dictionaries, you have to modify accessing values in filter:
myArray.filter{ (($0["rank"] as? Int) ?? 0) > 0 }
Hope it helps!
myArray.filter{ ((($0 as! NSDictionary)["rank"] as? Int) ?? 0) > 0 }
appending the answer of K.K Cast $0 to NSDictionary. I hope that will work

How can I limit the number of dictionaries in NSUserDefaults stored on the basis of userID in iOS

I have a dictionary having following details:
{
Name = "John";
Picture = (
""
);
Rating = 4;
},
{
Name = "Peter";
Picture = (
""
);
Rating = 3;
},
I am storing these dictionaries in NSUserDefaults. I want that a user having userID FED123RED123 can store only two such dictionaries in NSUSerDefaults and other user having different userID can store his two different values in NSUSerDefaults. In Short, how can I limit the number of dictionaries in NSUserDefaults stored on the basis of userID.
Arrange the structure something like this:
"FED123RED123" : [
{
Name = "John";
Picture = (
""
);
Rating = 4;
},
{
Name = "Peter";
Picture = (
""
);
Rating = 3;
}
]
And check if the count of array stored for particular user id is less than 2, then allow to add dictionaries.
You can create a variable of type Dictionary:
var dictionary_to_save: [[String:AnyObject]]!
Now, you may save the userDefaults to above dictionary and check the count of the same dictionary as above
var dictionary_to_save: [String:AnyObject]]?
func saving_to_defaults(){
let defaults = NSUserDefaults.standardUserDefaults()
let defaultsValue = defaults.objectForKey(object_name, forkey:"key_name")
self.dictionary_to_save = defaultsValue
if dictionary_to_save.count >= 2{
// do nothing or, count is already two, so delete dictionaries added before as
self.dictionary_to_save.removelast()
}else{
}
//save object using userDefault here
defaults.setObject(object_name, forKey: "key_name")
}

How to Sort an array in an ascending order swift 2.3

[{
msg = "Hi This is Jecky";
name = Susheel;
sender = 77;
timestamp = 1464241769520;
username = susheel;
}, {
msg = Dubai;
name = Jecky;
sender = 78;
timestamp = 1464246547147;
username = Jecky;
}, {
msg = "How are you ?";
name = Susheel;
sender = 77;
timestamp = 1464243480381;
username = susheel;
}, {
msg = "Aje dekhai nai";
name = Jecky;
sender = 78;
timestamp = 1464244974198;
username = Jecky;
}]
I have an array like this. I want to sort this array using timestamp in swift 2.3 or latest version of swift. Can anyone help me for this ?
let array=[
[
"msg":"Hi This is Jecky",
"name":"Susheel",
"sender":77,
"timestamp":1464241769520,
"username":"susheel",
],
[
"msg":"Dubai",
"name":"Jecky",
"sender":78,
"timestamp":1464246547147,
"username":"Jecky",
],
[
"msg":"How are you ?",
"name":"Susheel",
"sender":77,
"timestamp":1464243480381,
"username":"susheel",
],
[
"msg":"Aje dekhai nai",
"name":"Jecky",
"sender":78,
"timestamp":1464244974198,
"username":"Jecky",
],
]
print("array = \(array)")
let sortedArray=array.sort { (obj1, obj2) -> Bool in
return (obj1["timestamp"] as! Double) < (obj2["timestamp"] as! Double)
}
print("sortedArray = \(sortedArray)")
If your array is mutable you can user sortInPlace
yourArray.sortInPlace{$0.timestamp < $1.timestamp}
and if not, you can create a new array from sort, like suggested by Kristijan (although no need for parentheses on trailing closures):
let newArray = yourArray.sort{$0.timestamp < $1.timestamp}
You can get this functionality using extension:
extension NSArray{
//sorting- ascending
func ascendingArrayWithKeyValue(key:String) -> NSArray{
let ns = NSSortDescriptor.init(key: key, ascending: true)
let aa = NSArray(object: ns)
let arrResult = self.sortedArray(using: aa as! [NSSortDescriptor])
return arrResult as NSArray
}
//sorting - descending
func discendingArrayWithKeyValue(key:String) -> NSArray{
let ns = NSSortDescriptor.init(key: key, ascending: false)
let aa = NSArray(object: ns)
let arrResult = self.sortedArray(using: aa as! [NSSortDescriptor])
return arrResult as NSArray
}
}
use like this:
let array=[
[
"msg":"Hi This is Jecky",
"name":"Susheel",
"sender":77,
"timestamp":1464241769520,
"username":"susheel",
],
[
"msg":"Dubai",
"name":"Jecky",
"sender":78,
"timestamp":1464246547147,
"username":"Jecky",
],
[
"msg":"How are you ?",
"name":"Susheel",
"sender":77,
"timestamp":1464243480381,
"username":"susheel",
],
[
"msg":"Aje dekhai nai",
"name":"Jecky",
"sender":78,
"timestamp":1464244974198,
"username":"Jecky",
],
]
let a = NSArray.init(array: array)
let filArray = a.ascendingArrayWithKeyValue(key: "timestamp")
print(filArray)
customArray.sortInPlace {
(element1, element2) -> Bool in
return element1.someSortableField < element2.someSortableField
}
Check this out
https://www.hackingwithswift.com/example-code/arrays/how-to-sort-an-array-using-sort
To sort by property "timestamp"
array.sorted{$1["timestamp"] as? Long > $0["timestamp"] as? Long}
=> First, convert your Json to Objects. (check this link to do that :- http://roadfiresoftware.com/2015/10/how-to-parse-json-with-swift-2/ )
=> Then declare your Array as a typed array so that you can call methods when you iterate:
var array : [yourObjectClassName] = []
=> Then you can simply sort the value by :
array.sort({ $0.name > $1.name })
The above example sorts all the arrays by name. If you need to sort by timeStamp you can change the name to timeStamp ..etc
Check this link for more sorting examples : Swift how to sort array of custom objects by property value

Convert String Array to JSON or 2D Array SWIFT

I currently have a NSMutableArray "localArray" and I am trying to create that into a JSON Array or a 2D Array. I get this data my creating a database and running a query using a for loop on the database.
{
Food,
Burger,
3.99,
1.25,
POP,
Crush,
1.99,
.89,
and more.
}
The reason why I am looking for a JSON or 2d Array is I want to hold the data in the localArray in such a way that I can identify by type and then do something like .valueForKey("Name") or .valurForKey("Price") and add that to my tableview's cell text label or labels.
{
{
Type Food,
Name Burger,
Price 3.99,
Cost 1.25,
},
{
Type POP,
Name Crush,
Price 1.99,
Cost .89,
},
and more
}
I have already tried JSONSerialization, but that failed and also tried 2d Array but no luck.
Any help will be highly appreciated.
This is how I Query and add the data to localArray
let queryType = data.select(ada, code, name, proof, size, case_size, price)
.filter(bevType == type)
let rows = Array(queryType)
for row in rows{
let name = row[self.name]
let type = row[self.type]
let cost = row[self.cost]
let price = row[self.price]
localArray.addObject(name)
localArray.addObject(type)
localArray.addObject(cost)
localArray.addObject(price)
}
I solved it myself by creating a dictionary.
for row in rows{
var rDict: Dictionary = [String: String]()
rDict["Name"] = row[self.name]
rDict["Type"] = row[self.type]
rDict["Cost"] = row[self.cost]
rDict["Price"] = row[self.price]
localArray.addObject(rDict)
}
If fields are always repeating in count of 4, you can try doing this:
var array = [[String: AnyObject]]()
for var i = 0 ; i < array.count ; i += 4 {
var k = 0
var dict = [String: AnyObject]
dict["Type"] = array[i + k++]
dict["Name"] = array[i + k++]
dict["Price"] = array[i + k++]
dict["Cost"] = array[i + k]
array.append(dict)
}
Then extract dictionary from this swift array and use same keys to extract data from dictionary to be used in your cell like
let dict = array[indexPath.row]
cell.title = dict["Name"]

Resources