I have been searching for a while with no success and need an answer.
The data structure I am looking for is a dictionary that have a key and a value. The value is dictionary and have an array as a value.
For example:
"San Francisco" -> "Stores", -> "Apple Store", "...", ".."
"Companies" -> "...", ".."
"New York" -> "Fast Food" -> "Mc", "BK", "KFC"
How can I achieve this?
I tried with
var nest = [String: [String: [String]]]()
nest["New York"]["Fast Food"] = ["MC", "BK"]
This seems to not working properly.
However, I could do this
var fastfood = [String: [String]]()
var names = [String]()
fastFood["Fast Food"] = names
nest["New York"] = fastFood
This cause problem down the line. I need to create an object each time. I am fetching data from database and need to append the incoming data directly to the nest.
How about to create small data struct that will help you to manage data taxonomy.
Example:
struct CityTaxonomy {
let city: String
let taxonomy: [String:[String]]
}
CityTaxonomy(city: "San Francisco", taxonomy: ["Stores":["Apple Store", "...", ".."],"Companies":["...", ".."]])
Related
I have two arrays:
#State var myInterests: [String] = ["Beer", "Food", "Dogs", "Ducks"]
#State var otherInterests: [String] = ["Ducks", "Baseball", "Beer", "Pasta"]
I need to display a list with all shared interests listed first (top of the list), and then the others after.
ForEach(interests, id: \.self) { tag in
Text(tag)
}
The result for otherInterests should be something like:
["Ducks", "Beer", "Baseball", "Pasta"]
Is there any way of sorting the array to move the shared interests to the front of the array and the remaining ones after?
As long as the order of the subitems is not that important (you can sort each sublist to make sure consistent output) - a simple solution can be to use sets here!
Something like this
let myInterests: [String] = ["Beer", "Food", "Dogs", "Ducks"]
let otherInterests: [String] = ["Ducks", "Baseball", "Beer", "Pasta"]
// This will result only in the shared interests between my and other
let sharedInterests = Set(myInterests).intersection(Set(otherInterests))
// This will result in only the not shared interests
let resetOfOtherInterest = Set(otherInterests).subtracting((Set(sharedInterests)))
// Here we combine the two (which are disjoint!)
let newOtherInterest = Array(sharedInterests) + Array(resetOfOtherInterest)
print(newOtherInterest)
newOtherInterest = ["Ducks", "Beer", "Baseball", "Pasta"]
I have a list of dogs and need to fetch certain bits of data. In one case I need the row of names to show in a list, in other cases I need all or parts of the data from a single dog (name, gender, speed). I am fairly certain I should be using an array, although I started with a dictionary. I plan to add more parameters and allow users to add more dogs, so I am trying to find the most expandable option
struct Dog {
var name: String
var gender: String
var speed: Int
}
struct MyDogs {
let myDogs = [
Dog(name: "Saleks", gender: "Male", speed: 50),
Dog(name: "Balto", gender: "Male", speed: 70),
Dog(name: "Mila", gender: "Female", speed: 20)
]
}
WARNING I don't have my IDE available, may have a few syntax errors.
For reference, what you're demonstrating is not a multi-dimensional array. A 3d array is like this.
let some3DArray =
[["Hello", "World"],
["This", "Is", "An"],
["Multidimensional","Array"]]
To access the values in your example, based on what you're asking for you'd do it like so.
//To loop through all the dogs in your array. Useful for your "List"
for dog in yourDogs {
print(" Name: \(dog.name) "
}
// To find a dog based on some property you can do something like this.
let dog = {
for dog in yourDogs {
if dog.name == yourSearchValue {
return dog
} else {
//HANDLE NULL VALUE
//What do you want to happen if NO dog is found?
}
return null
}
}
// You can use the values from the array by accessing it directly via an index.
// This can be done with whatever conditional you need to specifically reach.
let specificDog = dogs[3]
// Once you have your copy of the specific dog you want to access.
// You can then get the values of that object.
let dogName = specificDog .name
let dogGender = specificDog .gender
let dogSpeed = specificDog .speed
Your use-case seems to be on the right track. An array would be useful and provide the most flexibility to add more dogs later down the road. This could be handled very easily for example by doing something like this. You can find out more about that here. Add an element to an array in Swift
var yourDogArray = [Dogs]()
yourDogArray.append(Dog(name: "xxx", gender: "female", speed: 20))
TableView(didSelectRowAt...)
This is a common usage And it works because your list that you populate is populated on an index from 0 to length which means if you select the first item on the list, it will match with your first item in your arrayCollection.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath {
let name = yourDogArray[indexPath.row].name
let gender = yourDogArray[indexPath.row].gender
let speed = yourDogArray[indexPath.row].speed
//Do whatever else you need to do here with your data. In your case you'd
//probably segue to the details view controller and present this data.
//Read up on Segue and Prepare for Segue to pass data between controllers.
}
I'm working on an IOS project that gets its data from Google's Firebase Firestore.
I have Documents like this in Firestore:
5lTSobXhcQBR2oG95s5q
Title: "ABC"
Timestamp: 1554374528.641053
FEeIAlAPlcrVvvtSKn8D
Title: "XYZ"
Timestamp: 1554443702.1300058
In my IOS project I have a Dictionary like this:
myDictionary: [String: [String: Any]] = [5lTSobXhcQBR2oG95s5q: ["Title": "ABC", "Timestamp": 1554374528.641053], FEeIAlAPlcrVvvtSKn8D: ["Title": "XYZ", "Timestamp": 1554443702.1300058]]
How can I sort my Dictionary by Timestamp?
If you are OK with getting back an array of tuples you can apply sorted() with a closure
let sortedTuples = myDictionary.sorted() {
if let t1 = $0.value["Timestamp"] as? Double, let t2 = $1.value["Timestamp"] as? Double {
return t1 < t2
}
return true
}
Note that I by default return true here if either of the values can't be cast to double or doesn't exist. A more advanced logic can of course be implemented depending on which of the two elements fails.
Every collection in iOS or swift has a sort function.
For example:
let sortedArray = dictionary.sort() { return $0.timestamp < $1.timestamp }
$0 will reference to 'the first' element and $1 the element after the first one.
In your example, the logic is the same.
I would do it like this:
Extract the timestamp data and store it in an extra dictionary with the id as a key and the value as a timestamp. Then I would use the .sort function to sort these elements in my dictionary.
I am just started to learn Swift and am new to ios development too.
var bookArray:[String:[[String:String]]] = ["book1":[["bookid":"SCIENCE","viewed":"12"],["bookid":"MATHS","viewed":"25"]],"book2":[["bookid":"HISTORY","viewed":"10"]]]
I will get the input as outer dictionary key and inner dictionary key, need to check and update dictionaries.
(i.e)
If the given outer dictionary key is "book1" and inner dictionary key is "MATHS" then the required output to be
bookArray:[String:[[String:String]]] = ["book1":[["bookid":"SCIENCE","viewed":"12"],["bookid":"MATHS","viewed":"26"]],"book2":[["bookid":"HISTORY","viewed":"10"]]]
(viewed count to be incremented)
If the given outer dictionary key is "book1" and inner dictionary key is "CHEMISTRY" then the required output to be
bookArray:[String:[[String:String]]] = ["book1":[["bookid":"SCIENCE","viewed":"12"],["bookid":"MATHS","viewed":"25"],["bookid":"CHEMISTRY","viewed":"0"]],"book2":[["bookid":"HISTORY","viewed":"10"]]]
(New Bookid to be added for the given outer key with viewed count as zero)
I started to work, but there was lot of complications with for loop and too many confusions...
Can some one suggest me some better way to accomplish the result?
Maybe the following code can help you get it to the final answer.
var myDict : [String:[[String: String]]] = [:]
myDict = ["book1": [["bookid":"SCIENCE","viewed":"12"], ["bookid":"MATHS","viewed":"25"]], "book2":[["bookid":"HISTORY","viewed": "10"]]]
func updateKey(_ outKey: String, _ innerKey: String){
var array = myDict[outKey] ?? []
if let index = array.firstIndex(where: {$0["bookid"] == innerKey}){
array[index]["viewed"] = "\(Int(array[index]["viewed"]!)! + 1)"
}
else {
array += [["bookid":innerKey,"viewed":"0"]]
}
myDict[outKey] = array
}
updateKey("book1", "MATHS")
print(myDict)
// ["book2": [["viewed": "10", "bookid": "HISTORY"]], "book1": [["viewed": "12", "bookid": "SCIENCE"], ["viewed": "26", "bookid": "MATHS"]]]
updateKey("book1", "CHEMISTRY")
print(myDict)
//["book2": [["viewed": "10", "bookid": "HISTORY"]], "book1": [["viewed": "12", "bookid": "SCIENCE"], ["viewed": "26", "bookid": "MATHS"], ["viewed": "0", "bookid": "CHEMISTRY"]]]
I would suggest creating a struct for Book
struct Book {
let bookID: String
let viewed: Int
}
and holding an array of that. Will be easier to manage.
Your array will change to:
var bookArray: [String:Book] = [Book(bookID: "SCIENCE", viewed: 12)]
You can create more books and add them to the array
I created an array that contains different numbers and each time the button is clicked the array advances to the next index number.
var currentNumber = 0
var random = ["1", "2", "3", "4", "5", "6"]
#IBAction func numberUp(sender: UIButton)
numberLabel.text = random[currentNumber]
++currentNumber
I tried to get similar results in with Parse but i couldn't. I created a class with a array in it
var numbers = PFObject(className:"Numbers")
numbers["number"] = ["1","2","3","4","5","6"]
numbers.save()
How would i go about doing the same thing but with the array i created on Parse. Or how could i retrieve the array from Parse and assign it to a local array ?
First you have to create a PFQuery like
let query = PFQuery(className: "Numbers")
Create a query to download the data in the table:
let result = query.find()
Then assume you have only one row in the table:
let arrayOfNumbers = result.first
Then you can iterate on arrayOfNumbers