Get all keys of nsdictionary sorted alphabetically in swift? - ios

I have got a NSDictionary with alphabets as keys. I want to get those keys sorted alphabetically . I have tried many methods but I am getting error on Sort() method. Can any one help me ????
Thanks in advance
Note:
1) I don't want to get a sorted array of dictionaries
2) I don't want to sort the dictionary by means of the values
(I am getting a lot of answers for this )

You can sort the keys this way:
let dictionary: NSDictionary = ["a" : 1, "b" : 2]
let sortedKeys = (dictionary.allKeys as! [String]).sorted(<) // ["a", "b"]
Swift 3:
let dictionary: NSDictionary = ["a" : 1, "b" : 2]
let sortedKeys = (dictionary.allKeys as! [String]).sorted(by: <) // ["a", "b"]

In Swift 2.2
You can sort like this in Ascending Order
let myDictionary: Dictionary = ["a" : 1, "b" : 2]
let sortedKeys = myDictionary.keys.sort() // ["a", "b"]
Descending Order
let myDictionary: Dictionary = ["a" : 1, "b" : 2]
let sortedKeys = myDictionary.keys.sort(>) // ["b", "a"]

For Swift 3
// Initialize the Dictionary
let dict = ["name": "John", "surname": "Doe"]
// Get array of keys
var keys = Array(dict.keys).sorted(by: >)
print(keys)

Related

How to sort a dictionary of [int: String] in Swift 5 [duplicate]

This question already has answers here:
Sort Dictionary by keys
(16 answers)
Closed 3 years ago.
I have an array that has integers as keys, and strings for values
var dictionary = [Int: String]()
All of these try's either end in compile error for Swift 5:
dictionary = dictionary.keys.sorted()
dictionary = (dictionary.sorted{ $0.key < $1.key })
dictionary = dictionary.sorted { $0.0 < $1.0 } .map { $0.1 }
reverseSortedValues = dictionary.sorted { $0.0 > $1.0 } .map { $0.1 }
dictionary = profileImagesDictionary.sorted(by: { $0.0.compare($1.0) == .OrderedAscending })
dictionary = profileImagesDictionary.sorted { $0.key
Code:
profileImagesDictionary = [Int : String](uniqueKeysWithValues: profileImagesDictionary.sorted{ $0.key > $1.key})
Console Output printed keys
before: dictionary = [3, 1, 2, 4, 0]
after: dictionary = [3, 0, 2, 1, 4]
I need it to rearrange the dictionary / actually sort it by keys.
So like instead of:
dictionary = [1: "a", 3: "c", 2: "b"]
It after being sorted would be:
dictionary = [1: "a", 2: "b", 3: "c"]
Simply give the following code to print sorted keys.
print(dictionary.keys.sorted)
Here you have a Dictionary not an Array, to sort your dictionary based on your keys you could use let sortedKeys = Array(dictionary.keys).sort(<) , but it only contains keys in array

Swift: Merge Array of dictionaries with duplicate key but unique values

I have a array of dictionaries which contains same key but different values. I want to merge these dictionaries and add all the values of same keys just like below:
var arrayofDict = [["2019":"A"],["2019":"B"],["2019":"C"],["2018":"A"],["2018":"c"],["2017":"A"],["2017":"B"],["2017":"C"],["2016":"A"],["2015":"A"],["2015":"B"]]
expected result as an Array like:
var newDict = [["2019":["A","B","C"]],["2018":["A","C"]],["2017":["A","B","C"]],["2016":["A"]],["2015":["A","B"]]]
This shows how to build a single dictionary. Your "expected result" is an array. Is this what you really expected or did you want an array?
You can iterate the dictionary items and build up the dictionary entries:
var arrayofDict = [["2019":"A"],["2019":"B"],["2019":"C"],["2018":"A"],["2018":"c"],["2017":"A"],["2017":"B"],["2017":"C"],["2016":"A"],["2015":"A"],["2015":"B"]]
var result = [String : [String]]()
for dict in arrayofDict {
for (key, value) in dict {
result[key, default: []].append(value)
}
}
print(result)
["2016": ["A"], "2018": ["A", "c"], "2015": ["A", "B"], "2019": ["A", "B", "C"], "2017": ["A", "B", "C"]]
Or, if you want an array:
let result2 = result.map { [$0.key: $0.value] }
print(result2)
[["2015": ["A", "B"]], ["2016": ["A"]], ["2019": ["A", "B", "C"]], ["2018": ["A", "c"]], ["2017": ["A", "B", "C"]]]
as #vacawama in more functional way
let result = arrayofDict.reduce(into: [String:[String]]()) { (acc, d) in
for key in d.keys {
// don't worry to force unwrap d[key], if key exist, the value is not nil
acc[key, default: []].append(d[key]!)
}
}

Swift array map with comma before append new value

i have this following data structure in my Realm object
var tags = List<Tag>()
"tags": [
{
"tagId": "80069",
"tagName": "A"
},
{
"tagId": "80070",
"tagName": "B"
},
{
"tagId": "80071",
"tagName": "C"
},
{
"tagId": "80073",
"tagName": "D"
}
]
So what i want to achieve is, I map all my tag name into my new array
this is my code
let realmObject = self.realm.objects(MyDTO.self)
let array = Array(realmOutletList).map{Array($0.tags).map{$0.tagName!}.joined(separator: ",")}
it prints out this
["A,B,C", "A,C,D", "B,C,D"]
What I want to achieve is like
["A","B","C", "A","C","D", "B","C","D"]
I need that kind of array because I am going to create a Set from the array and then compare with another array
The compared array will be like
["A","B","C", "A","C","D", "B","C","D"]
because of the compared Array and the realmObject Array is different, it always shows false when i use
let subset = filterSet.isSubset(of: mySet)
Can anyone guide me please??
Thanks
Let's walk through solving the issue:
Consider that you have:
let originalArray = ["A,B,C", "A,C,D", "B,C,D"]
First, we need to separate each string in originalArray by "," character, so we could do:
let modifiedArray = originalArray.map { $0.components(separatedBy: ",") }
We map it to transform each string to a strings array (separation).
So far, the output of modifiedArray would be:
[["A", "B", "C"], ["A", "C", "D"], ["B", "C", "D"]]
which is an array of strings array.
Second, we need to spilt each -string- array in modifiedArray (having one reduced strings array instead), so we could do:
var final = [String]()
for array in modifiedArray {
for string in array {
final.append(string)
}
}
OR by using reduce
let finalArray = modifiedArray.reduce([], +)
Therefore, finalArray would be:
["A", "B", "C", "A", "C", "D", "B", "C", "D"]
which is the desired result.
Conclusion
For a fully one-lined answer (following the high-order functions approach):
let originalArray = ["A,B,C", "A,C,D", "B,C,D"]
let desiredArray = originalArray.map { $0.components(separatedBy: ",") }.reduce([], +)
print(desiredArray) // ["A", "B", "C", "A", "C", "D", "B", "C", "D"]
Well, it's quite easy:
This
let array = Array(realmOutletList).map{Array($0.tags).map{$0.tagName!}.joined(separator: ",")}
should be this
let array = Array(realmOutletList).flatMap{Array($0.tags).map{$0.tagName!}}
That's all. And you will get your ["A","B","C", "A","C","D", "B","C","D"].

How do I sort an array of dictionary according to an array contents in Swift

I have an array of dictionary. I need to sort that array. The sorting shouldnt be like ascending or descending but it should be based on an another array contents.
EX: Lets say I have an array nammed array_unsorted and that array contains a lot of dictionary objects like d1, d2, d3, d4 etc. Each of the dictionary object has a key called key1 and each dictionary object has different value for that key such as Kammy, Maddy, Jessy. Lets say I have anohter sorted array which Maddy, Kammy, Jessy. Now the dictionary should be sorted in a way that the first element should the dictionary object in which the value for key1 should beMaddy`.
I cannot use SortDescriptor, because this will sort as an ascending or descending order based on the key passed to it.
I have tried my solution but I am ended up using so many nested loops. I feel like the solution I made so so pathetic that I dont even want to post the code here.
Any help would be so much appreciated.
EDIT: There can be multiple sorting arrays but as of now I am considering only one sorting array and then I can write the code for multiple sorting arrays.
How about this:
Create a new, empty dictionary with a String key, and a value of type Dictionary. Call it sourceItemsDict.
Loop through the dictionaries in your source array, and add each entry to your new dictionary, using your sort key as the dictionary key, and put the array entry as the value.
Create a new, empty array of dictionaries for your sorted results. call it sortedArray.
Now loop through your array that has the desired order in it. Fetch the item with that key from sourceItemsDict and append it to the end of sortedArray.
That should do it, and it should perform in O(n) time.
Try this:
func sort<T: Equatable>(arrayOfDict arr: [[String: T]], by key: String, order: [T]) -> [[String: T]] {
return arr.sorted {
guard let value0 = $0[key], let value1 = $1[key] else {
return false
}
guard let index0 = order.index(of: value0), let index1 = order.index(of: value1) else {
return false
}
return index0 < index1
}
}
let array_unsorted = [
["name": "Kammy", "city": "New York"],
["name": "Maddy", "city": "Cupertino"],
["name": "Jessy", "city": "Mountain View"]
]
let sortedByName = sort(arrayOfDict: array_unsorted, by: "name", order: ["Maddy", "Kammy", "Jessy"])
let sortedByCity = sort(arrayOfDict: array_unsorted, by: "city", order: ["Cupertino", "Mountain View", "New York"])
print(sortedByName)
print(sortedByCity)
Your question leaves a couple of unresolved scenarios:
1: What if the key is missing from a dictionary?
let array_unsorted = [
["name": "Kammy", "city": "New York"],
["city": "Las Vegas"],
["name": "Maddy", "city": "Cupertino"],
["name": "Jessy", "city": "Mountain View"]
]
let sortedByName = sort(arrayOfDict: array_unsorted, by: "name", order: ["Maddy", "Kammy", "Jessy"])
Should Las Vegas appear at the beginning or end of the sorted array?
2: What if you don't specify an order for a value?
let array_unsorted = [
["name": "Amy"],
["name": "Kammy", "city": "New York"],
["name": "Maddy", "city": "Cupertino"],
["name": "Jessy", "city": "Mountain View"]
]
let sortedByName = sort(arrayOfDict: array_unsorted, by: "name", order: ["Maddy", "Kammy", "Jessy"])
Now where should Amy be placed?
Check out this example:
let dic1 = ["name" : "a"]
let dic2 = ["name" : "b"]
let dic3 = ["name" : "c"]
let dic4 = ["name" : "d"]
let dic5 = ["name" : "e"]
let unsorted_array = [dic2,dic5,dic1,dic4,dic3]
func sortArrayByName(_ array:[[String:String]])->[[String:String]]{
var sortedArray:[[String:String]] = [[String:String]]()
var sortingOrder:[String] = [String]()
for eachDic in array{
if let name = eachDic["name"]{
sortingOrder.append(name)
sortingOrder.sort() // sorting logic here
if sortedArray.isEmpty{
sortedArray.append(eachDic)
} else {
let index = sortingOrder.index(of: name)!
sortedArray.insert(eachDic, at: index)
}
}
}
return sortedArray
}
let sorted_array = sortArrayByName(unsorted_array)

How to convert dictionary to array

I want to convert my dictionary to an array, by showing each [String : Int] of the dictionary as a string in the array.
For example:
    
var myDict: [String : Int] = ["attack" : 1, "defend" : 5, "block" : 12]
    
I'm aware of myDict.keys.array and myDict.values.array, but I want them to show up in an array together. Here's what I mean:
    
var myDictConvertedToArray = ["attack 1", "defend 5", "block 12"]
You can use a for loop to iterate through the dictionary key/value pairs to construct your array:
var myDict: [String : Int] = ["attack" : 1, "defend" : 5, "block" : 12]
var arr = [String]()
for (key, value) in myDict {
arr.append("\(key) \(value)")
}
Note: Dictionaries are unordered, so the order of your array might not be what you expect.
In Swift 2 and later, this also can be done with map:
let arr = myDict.map { "\($0) \($1)" }
This can also be written as:
let arr = myDict.map { "\($0.key) \($0.value)" }
which is clearer if not as short.
The general case for creating an array out of ONLY VALUES of a dictionary in Swift 3 is (I assume it also works in older versions of swift):
let arrayFromDic = Array(dic.values.map{ $0 })
Example:
let dic = ["1":"a", "2":"b","3":"c"]
let ps = Array(dic.values.map{ $0 })
print("\(ps)")
for p in ps {
print("\(p)")
}
If you like concise code and prefer a functional approach, you can use the map method executed on the keys collection:
let array = Array(myDict.keys.map { "\($0) \(myDict[$0]!)" })
or, as suggested by #vacawama:
let array = myDict.keys.array.map { "\($0) \(myDict[$0]!)" }
which is functionally equivalent
With Swift 5
var myDict:[String : Int] = ["attack" : 1, "defend" : 5, "block" : 12]
let arrayValues = myDict.values.map({$0})
let arrayKeys = myDict.keys.map({$0})
You will have to go through and construct a new array yourself from the keys and the values.
Have a look at 's swift array documentation:
You can add a new item to the end of an array by calling the array’s
append(_:) method:
Try this:
var myDict:[String : Int] = ["attack" : 1, "defend" : 5, "block" : 12]
var dictArray: [String] = []
for (k, v) in myDict {
dictArray.append("\(k) \(v)")
}
Have a look at What's the cleanest way of applying map() to a dictionary in Swift? if you're using Swift 2.0:

Resources