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
Related
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 have array of dates (strings) which are coming from local data base like following.
datesFromDBArray:["04/12/2017 07:10:41", "04/12/2017 07:12:17", "04/12/2017 07:13:54", "04/12/2017 07:17:45", "04/12/2017 07:18:56", "05/12/2017"]
Here, same date can have multiple times.
Also from same data base, I am getting some other data called actions.
ActionsDBArray:["1", "6", "1", "1", "1", "2", "2", "2", "4", "1", "5", "2", "3"]
these above two data getting from local database. And both arrays number of count is equal.
Now, I am getting number of dates from server response. That is like
TotalDaysServerArray:["22/11/2017 11:59:59", "23/11/2017 11:59:58", "24/11/2017 11:59:57"]
Here, I am showing TotalDaysServerArray data in table view.
So, here, If user pressed on first cell like 22/11/2017 11:59:59, I need to check this date (not time, only same date) is existed in datesFromDBArray, if existed, then need to check how many indexes its existed, and need to fetch ActionsDBArray same indexes data.
So, I need to get the list of ActionsDBArray indexes and need to show the list of that in some other place.
I have tried some logic which was not worked, so, I am posting query here.
Can anyone suggest me, how to achieve this?
let clickedStr = TotalDaysServerArray[indexPath.row]
let str = clickedStr.components(separatedBy: " ").first
for(index , value) in datesFromDBArray.enumerated() {
if str == value.components(separatedBy: " ").first! {
print(ActionsDBArray[index])
}
}
It's child's play , Don't know where you stuck in logic
Note: I have added First object manually in 04/12/2017 07:10:41 to test the logic
var datesFromDBArray = ["04/12/2017 07:10:41", "04/12/2017 07:12:17", "04/12/2017 07:13:54", "04/12/2017 07:17:45", "04/12/2017 07:18:56", "05/12/2017"]
var ActionsDBArray = ["1", "6", "1", "1", "1", "2", "2", "2", "4", "1", "5", "2", "3"]
var TotalDaysServerArray = ["04/12/2017 11:59:59","22/11/2017 11:59:59", "23/11/2017 11:59:58", "24/11/2017 11:59:57"]
let findingValue = TotalDaysServerArray.first!
print(findingValue)
let index = datesFromDBArray.index { (string) -> Bool in
string.components(separatedBy: " ").first == findingValue.components(separatedBy: " ").first
}
print(index)
if let i = index {
print("Your Object in ActionsDBArray \(ActionsDBArray[i])")
}
Output :
04/12/2017 11:59:59
Optional(0)
Your Object in ActionsDBArray 1
Hope it is helpful to you
I want to implement a multiple click in my Shinobi DataGrid. I have a grid which have array
( ["1", "32", and more] )
If I click the grid I put it into new Array self.arrayNr.append(currNr).
But I want to check and remove if currNr is already exist in arrayNr it is will be remove from the arrayNr.
I'm new and using Swift 3. I read some question regarding with my question like this and this but it's not working. I think the Swift 2 is simpler than Swift 3 in handling for String. Any sugesstion or answer will help for me?
You can use index(of to check if the currNrexists in your array. (The class must conform to the Equatable protocol)
var arrayNr = ["1", "32", "100"]
let currNr = "32"
// Check to remove the existing element
if let index = arrayNr.index(of: currNr) {
arrayNr.remove(at: index)
}
arrayNr.append(currNr)
Say you have an array of string, namely type [String]. Now you want to remove a string if it exists. So you simply need to filter the array by this one line of code
stringArray= stringArray.filter(){$0 != "theValueThatYouDontWant"}
For example, you have array like this and you want to remove "1"
let array = ["1", "32"]
Simply call
array = array.filter(){$0 != "1"}
Long Solution
sampleArray iterates over itself and removes the value you are looking for if it exists before exiting the loop.
var sampleArray = ["Hello", "World", "1", "Again", "5"]
let valueToCheck = "World"
for (index, value) in sampleArray.enumerated() {
if value == valueToCheck && sampleArray.contains(valueToCheck) {
sampleArray.remove(at: index)
break
}
}
print(sampleArray) // Returns ["Hello", "1", "Again", "5"]
Short Solution
sampleArray returns an array of all values that are not equal to the value you are checking.
var sampleArray = ["Hello", "World", "1", "Again", "5"]
let valueToCheck = "World"
sampleArray = sampleArray.filter { $0 != valueToCheck }
print(sampleArray) // Returns ["Hello", "1", "Again", "5"]
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":["...", ".."]])
I have spent some time trying to search for this and I haven't found a solution. I am trying to access a specific array value in a dictionary. Below is the general code/explanation for what I want to do.
var dict = ["1": [1,2,3,4,5], "2": [6,7,8,9,10], "3": [11,12,13,14,15]]
//now lets say I want to access the 3rd value of dict["2"] = 8
//I have tried the following and failed
print(dict["2": [2]])
print(dict["2"][2])
Thanks
Here is the way you can achieve that:
var dict = ["1": [1,2,3,4,5], "2": [6,7,8,9,10], "3": [11,12,13,14,15]]
let temp = dict["2"]![2] // 8