Swift Issue - Dictionary with Two-dimensional Array in Array list - ios

I am trying to figure it out what is wrong with my code because XCode doesn't accept to run this code. Any idea what is wrong with it?
var dictionary = [String: [[String]]]()
var array = [[AnyObject]]()
dictionary["1"] = [["A", "A"], ["A1", "A2"]]
dictionary["2"] = [["B", "B"], ["B1", "B2"]]
dictionary["3"] = [["C", "C"], ["C1", "C2"]]
for i in 1...3 {
array.appendContentsOf([dictionary["\(i)"]!])
}
print(array)
This is what I am planning to have like this output:
[[["A", "A"], ["A1", "A2"]], [["B", "B"], ["B1", "B2"]], [["C", "C"], ["C1", "C2"]]]
This what I got an error from Xcode:
An internal error occurred. Source editor functionality is limited.
Note: The most bizarre part about this if I removed this line: array.appendContentsOf([dictionary["(i)"]!]) and it doesn't have an error but if I added this line then I got an error from Xcode

You were very close! A couple changes:
array needed to be defined as [[[String]]]() instead of [[AnyObject]](). AnyObject and String are not compatible for appending. Also, another layer of [] was added as your goal was an array 3 deep, not 2.
Changed array.appendContentsOf([dictionary["\(i)"]!]) to array += [dictionary["\(i)"]!] as this is compatible across all versions of Swift and keeps the appended argument from being unwrapped.
This provides the correct answer (tested in Swift Playground):
var dictionary = [String: [[String]]]()
var array = [[[String]]]()
dictionary["1"] = [["A", "A"], ["A1", "A2"]]
dictionary["2"] = [["B", "B"], ["B1", "B2"]]
dictionary["3"] = [["C", "C"], ["C1", "C2"]]
for i in 1...3 {
array += [dictionary["\(i)"]!]
}
// console:
// [[["A", "A"], ["A1", "A2"]], [["B", "B"], ["B1", "B2"]], [["C", "C"], ["C1", "C2"]]]
print(array)

Related

How to sort a CSV string based on the inner values?

I have this CSV String
"B,C,D,A,E\n18945,12091,14058,2907,15132\n25,122,134,428,211"
which I have separated by \n and , and got below array:
I have this array:
[["B", "C", "D", "A", "E"], ["18945", "12091", "14058", "2907", "15132"], ["25", "122", "134", "428", "211"]]
where first array inside the main array is indicating the column names, which I need to sort alphabetically based on that the remaining arrays should also sorted.
Consider a table like this:
B -> 18945 -> 25
After sort, I am expecting an output like this:
[["A", "B", "C", "D", "E"], ["2907", "18945", "12091", "14058", "15132"], ["428", "25", "122", "134", "211"]]
IMO you should try to structure your data but if you really want to go through this path you just need to sort the first collection indices and map the collections using the sorted indices. Of course this assumes all collections have the same number of elements and the collection is not empty:
let table = [["B", "C", "D", "A", "E"], ["18945", "12091", "14058", "2907", "15132"], ["25", "122", "134", "428", "211"]]
let indices = table[0].indices.sorted { table[0][$0] < table[0][$1] }
let sorted = table.map { collection in
indices.map { collection[$0] }
}
If you want to be extra paranoid and make sure your code will never crash you can get the first collection using if let and use compact map checking if the collection contains each index before accessing them using subscript:
let table = [["B", "C", "D", "A", "E"], ["18945", "12091", "14058", "2907", "15132"], ["25", "122", "134", "428", "211"]]
if let columns = table.first {
let indices = columns.indices.sorted { columns[$0] < columns[$1] }
let sorted = table.map { collection in
indices.compactMap { collection.indices ~= $0 ? collection[$0] : nil }
}
print(sorted)
}
edit/update:
For a case insensitive sort:
let indices = columns.indices.sorted { columns[$0].caseInsensitiveCompare(columns[$1]) == .orderedAscending }
For a case and diacritic insensitive sort:
let indices = columns.indices.sorted { columns[$0].localizedStandardCompare(columns[$1]) == .orderedAscending }
This will print
[["A", "B", "C", "D", "E"], ["2907", "18945", "12091", "14058", "15132"], ["428", "25", "122", "134", "211"]]

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]!)
}
}

Combining 2 Array into dictionary [duplicate]

This question already has answers here:
Swift equivalent to `[NSDictionary initWithObjects: forKeys:]`
(5 answers)
Closed 3 years ago.
I want to combine 2 array.
arr1 = ["a", "b", "c"]
arr2 = ["1", "2", "3"]
i want to make it to be :
"a" = "1"
"b" = "2"
"c" = "3"
so if i call value "1" into label1, it means value "a" is also called into label2 just like dictionary or index.
Just like that:
let arr1 = ["a", "b", "c"]
let arr2 = ["1", "2", "3"]
let dictionary = Dictionary(uniqueKeysWithValues: zip(arr1, arr2))
It's one line code
let dict = zip(["a", "b", "c"], ["1", "2", "3"]).compactMap{[$0.0:$0.1]}.reduce([:]) { $0.merging($1) { (current, _) in current } }
print(dict)
["a": "1", "b": "2", "c": "3"]
I suggests you to use user28434's answer which is more effective than mine. I am keeping my answer as alternative second best solution

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"].

Get all keys of nsdictionary sorted alphabetically in swift?

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)

Resources