Swift - Working with Dictionaries - Add multiple values

一笑奈何 提交于 2019-12-22 00:03:11

问题


I've been looking for answers to this problem, but unfortunately without success.

I'm developing a mathematical app (Swift-based), which keeps data of every function the user enters.

(I then need to draw the functions on an NSView using a Parser)

The data structure is saved into a Dictionary but I'm not able to add values and keys.

The Dictionary is initialized like:

var functions = [String : [[String : NSBezierPath], [String : NSColor], [String : CGFloat], [String : Bool]]]();

//1A.The String key of the main Dictionary is the value of the function, such as "sin(x)"
//1B.The value of the `Dictionary` is an `Array` od `Dictionaries`

//2.The first value is a dictionary, whose key is a String and value NSBezierPath()
//3.The second value is a dictionary, whose key is a String and value NSColor()
//4.The third value is a dictionary, whose key is a String and value CGFloat()
//5.The first value is a dictionary, whose key is a String and value Bool()

To add the functions, I have implemented a method (I will report a part of) :

...

//Build the sub-dictionaries

let path : [String:NSBezierPath] = ["path" : thePath];
let color : [String:NSColor] = ["color" : theColor];
let line : [String:CGFloat] = ["lineWidth" : theLine];
let visible : [String:Bool] = ["visible" : theVisibility];

//Note that I'm 100% sure that the relative values are compatible with the relative types.
//Therefore I'm pretty sure there is a syntax error.


//Add the element (note: theFunction is a string, and I want it to be the key of the `Dictionary`)

functions[theFunction] = [path, color, line, visible]; //Error here

...

I'm given the following error:

'@|value $T10' is not identical to '(String,[([String:NSbezierPath],[String : NSColor],[String : CGFloat],[String : Bool])])'

I hope the question was enough clear and complete.

In case I will immediately add any kind of information you will need.

Best regards and happy holidays.


回答1:


Dictionaries map from a specific key type to a specific value type. For example, you could make your key type String and your value type Int.

In your case, you’ve declared quite a strange dictionary: a mapping from Strings (fair enough), to an array of 4-tuples of 4 different dictionary types (each one from strings to a different type).

(It’s a new one on me, but it looks like this:

var thingy = [String,String]() 

is shorthand for this:

 var thingy = [(String,String)]()  

Huh. Strange but it works. Your dictionary is using a variant of this trick)

This means to make your assignment work you need to create an array of a 4-tuple (note additional brackets):

functions[theFunction] = [(path, color, line, visible)]

I’m guessing you didn’t mean to do this though. Did you actually want an array of these 4 different dictionary types? If so, you’re out of luck – you can’t store different types (dictionaries that have different types for their values) in the same array.

(Well, you could if you made the values of the dictionary Any – but that’s a terrible idea and would be nightmare to use)

Probably the result you wanted was this (i.e. make the functions dictionary map from a string to a 4-tuple of dictionaries of different types):

var functions = [String : ([String : NSBezierPath], [String : NSColor], [String : CGFloat], [String : Bool])]()

You’d assign values to the dictionary like this (note, no square brackets on the rhs):

functions[theFunction] = (path, color, line, visible)

This will work but it will be pretty unpleasant to work with. But do you really want to store your structured data in dictionaries and arrays? This isn’t JavaScript ;-) You’ll tie yourself in knots navigating that multi-level dictionary. Declare a struct! It’ll be so much easier to work with in your code.

struct Functions {
    var beziers: [String:NSBezierPath]
    var color: [String:NSColor]
    var line: [String:NSColor]
    var floats: [String:CGFloat]
    var bools: [String:Bool]
}
var functions: [String:Functions] = [:]

Even better, if all the beziers, colors etc are supposed to be references with the same key, declare a dictionary that contains all of them or similar.



来源:https://stackoverflow.com/questions/27662294/swift-working-with-dictionaries-add-multiple-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!