Usually I just step into the dictionary and find the value once inside. In this case, I need to step in, loop through to find a value then step back out again then find a different value. Example:
address_components": [
{
"long_name": "E3 2AA",
"short_name": "E3 2AA",
"types": [
"postal_code"
]
},
{
"long_name": "London",
"short_name": "London",
"types": [
"postal_town"
]
}
]
This is what googles api dictionary looks like and I need to fetch the long_name of the postal_town.
You can use the first(where: function passing a closure to filter for the type, this avoids a loop:
if let addressComponents = json["address_components"] as? [[String:Any]],
let postalTownComponent = addressComponents.first(where: { ($0["types"] as! [String]).contains("postal_town") }) {
print(postalTownComponent["long_name"])
}
This should do it for you:
let result = addressComponents.filter({ return ($0["types"] as! [String]).contains("postal_town") }).map({ $0["long_name"] })
address_components is an array so you can just loop over it and check the value of your key. Maybe something like:
var names = []
for entry in addressComponent {
if addressComponent["types"][0] == "postal_town" {
names.append(addressComponent["long_name"])
}
}
Should it just that simple, or I misunderstand your question? An example:
let dict = [ "long_name": "E3 2AA", "short_name": "E3 2AA"]
for (key, value) in dict {
print("your key: \(key) and value: \(value)")
}
Related
I have this model:
struct Class {
var field: [String: Field]
}
struct Field {
var type: String
}
And this array:
let classes: [Class] = [
Class(field: ["test": Field(type: "STRING"),
"test2": Field(type: "STRING"),
"test3": Field(type: "NUMBER")]),
Class(field: ["test": Field(type: "POINTER"),
"test2": Field(type: "STRING"),
"test3": Field(type: "STRING")]),
]
I would like to reduce all the types properties in a Set of Strings, I tried this:
let result = classes.map { $0.field.reduce([], { $0 + $1.value.type }) }
But instead of getting a set of strings:
What I would like to get
"STRING", "NUMBER", "POINTER"
I get an array of characters:
[["S", "T", "R", "I", "N", "G", "N", "U", "M", "B"....]]
What should I write instead? Thank you for your help
You can use flatMap to flatten the arrays of values and then use Set to get rid of non-unique values:
let result = Set(classes.flatMap { $0.field.values }.map { $0.type })
If you need an Array instead of a Set, you can simply wrap the above in Array()
I have a dictionary of type [String: Any] and I cannot get the total number of elements of internal dictionary.
struct ICP {
let staff = [
"teachers": [
[
"name": "Teacher One"
],
[
"name": "Teacher Two"
],
[
"name": "Teacher Three"
],
[
"name": "Teacher Four"
]
]
] as [String : Any]
}
I need to get the total number of teachers from the above dictionary.
First of all inside ICP struct you declared a constant variable named staff which contains a dictionary of kind [String: [[String: String]]] or shortly [String: [Any]], when you access teachers then you have a collection of single dictionaries which is kind of [[String: String]].
I suggest you to create a method inside the ICP class and call it teachersCount
Swift 5.1
Like:
struct ICP {
func teachersCount() -> Int {
guard let teachers = staff["teachers"] as? [[String: String]] else {return 0}
return teachers.count
}
You can call it outside of struct like:
ICP().teachersCount()
And Inside your struct like:
self.teachersCount()
struct Country {
var translations : [String:String?]? // must be defined as optionals!
}
// example entry
translationsDict = [
"translations": [
"de":"Deutschland",
"en": "germany",
"it": nil
]
]
How can I extract the values "Deutschland" and "germany" into a new array?
result should be:
["germany", "Deutschland"]
Firstly, get a collection of all values of translations, then convert it to an array.
if let collection = translationsDict["translations"]?.values {
let array = Array(collection)
print(array)
}
or
if let array = translationsDict["translations"]?.map({ $0.1 }) {
print(array)
}
I have response from server I want to filter it and store in array using swift. Please help how to do it.
self.countryArrayvalue = (json?["list"] as! [Dictionary<String, Any>] as! NSArray) as! [Dictionary<String, Any>]
now i want to get country name from this self.countryArrayvalue and store in array.
Response is:
{
"error": false,
"error_code": 200,
"list": [
{
"country_id": "1",
"country_name": "Afghanistan",
"iso_code": "AF"
},
{
"country_id": "2",
"country_name": "Aland Islands",
"iso_code": "AX"
},
{
"country_id": "3",
"country_name": "Albania",
"iso_code": "AL"
} ]
}
You are making too many casting instead of single one.
self.countryArrayvalue = json?["list"] as! [[String: Any]]
Now to get array of country name try like this way.
self.countryNamesArray = self.countryArrayvalue.flatMap { $0["country_name"] as? String }
I've got an object in Swift that is a dictionary of type Dictionary<String, String[]>. I'd like to be able to filter the String[] array whilst maintaining the dictionary structure.
let list: Dictionary<String, String[]> = [
"Vegetables" : [ "Carrot", "Potato" ],
"Fruit" : [ "Apple", "Orange", "Banana" ]
]
I'd like to be able to filter for everything containing an "O", and end up with something that looks like this:
[
"Vegetables" : [ "Carrot", "Potato" ],
"Fruit" : [ "Orange" ]
]
To filter the arrays, I've been doing this:
["Carrot", "Potato"].filter { ($0 as NSString).containsString("o") }
However, the part I'm struggling with now is mapping over the dictionary - because then I can preserve the key and call that filter function on the value. How would I go about doing this? Thanks in advance!
You can do it in a for in loop:
for (key, array) in list {
list[key] = array.filter { ($0 as NSString).containsString("o") }
}
You can also add your own map method to Dictionary:
extension Dictionary {
func map(f: (KeyType, ValueType) -> ValueType) -> [KeyType:ValueType] {
var ret = [KeyType:ValueType]()
for (key, value) in self {
ret[key] = f(key, value)
}
return ret
}
}
Then you can simply do:
var filteredList = list.map { $1.filter { ($0 as NSString).containsString("o") } }
Note: My implementation of map on Dictionary returns a copy of the dictionary to be more like the map method of Array
You can enumerate it and filter in 1 go. I just made list a variable instead of a const to make it simpler. Here is the code:
//it's a variable
var list: Dictionary<String, String[]> = [
"Vegetables" : [ "Carrot", "Potato" ],
"Fruit" : [ "Apple", "Orange", "Banana" ]
]
for (key, array) in list {
list[key] = array.filter({
(x : String) -> Bool in
return !(x.rangeOfString("o", options: NSStringCompareOptions.CaseInsensitiveSearch, range: nil, locale: nil).isEmpty)
})
}
NSLog("%#", list)
The output will be :
{
Fruit = (
Orange
);
Vegetables = (
Carrot,
Potato
);
}