Swift - Append Data To Custom Dictionary<Int, T> [closed] - ios

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I use a library Swift have defined a Dictionary
var data = [Int: [(TimelinePoint, UIColor, String, String, String?, [String]?, String?)]]()
var timelineObject = [(TimelinePoint, UIColor, String, String, String?, [String]?, String?)]()
for (index, transaction) in days.enumerated() {
//this line working
data = [0: timelineObject, 1: timelineObject, 2: timelineObject, 3: timelineObject]
//this line not working
data = [index: timelineObject]
}
=> How I can add data to the dictionary in for loop?

Instead of using such large tuples, you must create a struct/class and use that.
Then use subscript to add values to the Dictionary.
Example:
struct Model {
let point: TimelinePoint
let color: UIColor
//add other properties..
}
var data = [Int: [Model]]()
data[0] = Model(point:..., color: .red)
data[1] = Model(point:..., color: .black)

data = [index: timelineObject] // wrong
replace it with
data[index] = timelineObject // right
I would suggest you to read how to work with dictionaries : Apple Documentation

Related

Doubts about Swift initializers [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed last year.
Improve this question
I know this sounds like a silly question for all of you but I wanted to have more clarity on the differences of using init() or not in a structure
I meant that whether I use init() or not the parameters are still required. That's why I was wondering the difference of using init() or simple variables.
1^ Example without init()
struct ProductsImageView: View {
var image: String
var title: String
var time: Int
var isAllInOne: Bool = false
var body: some View {
}
}
2^ Example with init()
struct ProductsImageView: View {
var image: String
var title: String
var time: Int
var isAllInOne: Bool
init(image: String, title: String, time: Int, isAllInOne: Bool = false) {
self.image = image
self.title = title
self.time = time
self.isAllInOne = isAllInOne
}
var body: some View {
}
}
In both cases the various parameters will still be required when we call a structure in the code
ProductsImageView(image: "slider3", title: "Lorem", time: 60, isAllInOne: true)
Now I wanted to know when is it right to use init() and when not?
What are the differences?
Excuse me again for the stupid question but I prefer to have clear what I learn often I have some doubts and I ask you
If you don't write an init in the struct declaration, Swift will synthesize one for you. The init you wrote in example 2 is exactly the same as what Swift synthesizes in example 1.
However, the visibility of the synthesized init is always internal, even if the struct is public. So when you're creating a public struct and you want its init to be visible in other modules, you must write out its public init explicitly.

Swift Can't append to String array [duplicate]

This question already has answers here:
Simple swift array append not working
(3 answers)
Closed 4 years ago.
I have this array defined inside a class:
var pickOption: [String]?
inside my classes init, I am trying to append to the array:
override init!(reuseIdentifier identifier: String!) {
self.pickOption?.append("aaa")
print(self.pickOption)
}
but self.pickOption is returning nil, why? and how can I fix it?
With first statement var pickOption: [String]? you have just declared the array of type string but never allocate the memory. As this is optional type, it will be nil at the time of declaration.
You need to allocate memory for array before using it. You can declare array as this var pickOption = [String]() and rest of code will do the work!!
You have to init it declare it like this
var pickOption = [String]()
as this line
self.pickOption?
with the optional won't run as in it's moment pickOption is nil

Could not cast value of type(NSSingleEntryDictionary) [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I am getting the below error. My app is crashing for this reason.
Could not cast value of type '__NSSingleEntryDictionaryI' (0x1015f8210) to 'NSMutableDictionary'
All I am doing is :
var tempDict = self.arrayData.object(at: indexPath.row) as!
NSMutableDictionary
I have checked the others answers on stack but unfortunately they were not helpful for me.
Can anybody suggest me why this is happening?
Any help would be higgle appreciated!!
Simply do not use mutable Foundation collection types (NSMutable..) at all in Swift. They are not related to the Swift counterparts and you cannot cast an collection object to NSMutable...
Declare arrayData as native Swift array of dictionaries
var arrayData = [[String:Any]]()
and change the line to get the dictionary to
var tempDict = self.arrayData[indexPath.row]
Less code, no type cast and tempDict is mutable with the var keyword.
Dictionary denotes with {} and Array denotes with [] // In printed response you may have array with ()
So, your tempDict part is Array of Dictionary...You have to parse it like
var tempDict = self.arrayData.object(at: indexPath.row) as! [[String : Any]]
although please not use force unwrap .. either use if let or guard statement
if let tempDict = self.arrayData.object(at: indexPath.row) as! [[String : Any]]
{
// do something
}
else
{
// catch the error
}

Generics for repeated task with associated data - Swift

I've been trying to wrap my mind around a seemingly simple task, but keep getting nowhere.
My goal is to create a user-choice flow.
Let's say I have a list of food-related questions like :
What is your favourite breakfast? What do you have for dinner? How do you like
your meat cooked? Whats your favourite spaghetti sauce? e.t.c.
And a set of reply options for each question
Q1: <<Pancakes|Waffles>>, Q2: <<Steak|Spaghetti>>, Q3: <<Raw|Welldone>>, Q4: <<Bolognese|Simple cheese>>
How do i load a next question with a set of reply options depending on the users choice in the previous question? But the main trouble is how do i make it generic and data-driven - without the need for a bunch of conditionals.
I've been trying to work with Arrays, NSDictionaries, NSRegularExpressions but can't come up with a proper logical solution.
Any insights are very appreciated!
Thank you in advance.
An alternative to dictionaries would be a custom class. I think it improves readability but you may have your own opinion.
class Question {
var ask: String
var answers: [String]
var nextQuestions = [Question?]()
init(question: String, ans: [String]) {
self.ask = question
self.answers = ans
}
func nextQuestion(answer: String) -> Question? {
var result: Question? = nil
if let index = find(self.answers, answer) {
result = self.nextQuestions[index]
}
return result
}
}
// Set up your test data
let q1 = Question(question: "What is your favourite breakfast", ans: ["Pancakes", "Waffles"])
let q2 = Question(question: "What do you have for dinner", ans: ["Steak", "Spaghetti"])
let q3 = Question(question: "How do you like your meat cooked", ans: ["Raw", "Welldone"])
let q4 = Question(question: "What's your favourite spaghetti sauce", ans: ["Bolognese", "Simple cheese"])
// This is quick and dirty.
// It would be better to have a func to hide the implementation.
q1.nextQuestions.append(q2)
q1.nextQuestions.append(q2)
q2.nextQuestions.append(q3)
q2.nextQuestions.append(q4)
// Pretend "Spaghetti" was the answer for q2
var theQuestion = q2
let userAnswer = "Spaghetti"
if let another = theQuestion.nextQuestion(userAnswer) {
theQuestion = another
}
An obvious solution would be a dictionary of questions which holds another dictionary of related answers and their possible (follow up) questions. Something like:
[Question: [Answer:Question]]
The question in the second dictionary then refers (recursive) to a question in the first one.

Extending Array to append SKTextures [duplicate]

This question already has answers here:
Is it possible to make an Array extension in Swift that is restricted to one class?
(4 answers)
Closed 7 years ago.
Being fairly new to Swift I decided I would look at extending Array (or more specifically [SKTexture] Arrays of SKTexture) with a function to add a specified number of frames from the application bundle.
// FRAMES
FuzzyRabbit_0001#2x.png
FuzzyRabbit_0002#2x.png
FuzzyRabbit_0003#2x.png
FuzzyRabbit_0004#2x.png
// CALL
var rabbitTextures = [SKTexture]()
self.rabbitTextures.textureFromFrames("FuzzyRabbit", count: 4)
My first attempt is listed below, I am getting the error Cannot invoke 'append' with an argument list of type '(SKTexture!)' which from looking at the function fuzzyPush is because I am trying to append an SKTexture rather than the generic T.
Is this possible, or am I limited by the fact that I don't want the function to be generic but rather specific to Arrays of SKTexture.
extension Array {
// ONLY SKTexture
mutating func textureFromFrames(imageName: String, count: Int) {
if !(self[0] is SKTexture) { return }
for index in 1...count {
let image = String(format: "\(imageName)_%04d", index)
let texture = SKTexture(imageNamed: image)
self.append(texture) // ERROR: Cannot invoke append with an argument list of type SKTexture!
}
}
// WORKS FINE
mutating func fuzzyPush(newItem: T) {
self.append(newItem)
}
}
I was just curious if this is something I could do with an extension, its not a problem as I have this as a function that takes 3 parameters (imageName, count, arrayToAppend) so I can quite easily use that.
This extension is not possible to write today. You cannot apply an extension method to only certain types of arrays.
There are two good solutions. You can use a HAS-A pattern by creating a struct (TextureList) that contains a [SKTexture], or you can use a function.
You can replace :
self.append(texture)
with
self.append(texture as T)
I checked this on an array of strings though and it worked.
About the first check add another check to see if the array is empty otherwise the self[0] is SKTexture will fail.
This is the code I tested on an online swift compiler (SKTexture was not available obviously) :
extension Array {
mutating func textureFromFrames(imageName: String, count: Int) {
for index in 1...count {
let image = String(format: "\(imageName)_%04d", index)
self.append(image as T)
}
}
}
var arr = Array<String>()
arr.textureFromFrames("testing", count:4)
for tmp in arr {
println("\(tmp)")
}

Resources