I currently have this:
var locations = [
["location": "New York", "temp": "2 °C", "wind": "3 m/s"]
]
And I add stuff to this with locations.append(). It works great!
However, I don't want there to be a default entry. So I tried
var locations = [] // Not working.
var locations = [] as NSArray
var locations = [] as NSMutableArray
var locations = [] as NSDictionary
var locations = [] as NSMutableDictionary
var locations = [:] as ... everything
var locations = [APIData]
Feels like I've tried everything but I still get countless errors whatever I try. At this stage I'm even surprised my default locations is working.
How do I solve this? How do I make locations empty to start with?
If we assume you try to initialize a array of dictionary with key String and value String you should:
var locations: [[String: String]] = []
then you could do:
locations.append(["location": "New York", "temp": "2 °C", "wind": "3 m/s"])
To create an array or dictionary you should know the type you need.
With
var array: [String]
you declare a variable to contain an array of strings. To initialize it, you can use
var array: [String] = [String]()
You can omit the : [String] because the compiler can automatically detect the type in this case.
To create a dictionary you can do the same, but you need to define both, the key and the value type:
var dictionary = [String: String]()
Now, what you ask for is an array of dictionaries, so you need to combine both to
var arrayOfDictionaries = [[String: String]]()
Related
Add two dictionary values in a new array. the array values will remain unchanged from its position. I need to add two dictionary values in a new array. The values added in the array must remain constant at every run.
var dictionary1:[String:Int] = ["Mohan":75, "Raghu":82, "John":79]
var dictionary2:[String:Int] = ["Surya":91, "John":79, "Saranya":92]
dictionary1.merge(dictionary2){(current, _) in current}
var arr : [String] = []
for (key, value) in dictionary1 { arr.append("(key) (value)") }
print(dictionary1)
Simply use append(contentsOf:) to add the contents of dictionary1 and dictionary2 to arr. Use map(_:) to format the key-value pairs while adding to the array.
let dictionary1 = ["Mohan":75, "Raghu":82, "John":79]
let dictionary2 = ["Surya":91, "John":79, "Saranya":92]
var arr = [String]()
arr.append(contentsOf: dictionary1.map({"\($0.key) \($0.value)"}))
arr.append(contentsOf: dictionary2.map({"\($0.key) \($0.value)"}))
print(arr) //["Mohan 75", "John 79", "Raghu 82", "Surya 91", "John 79", "Saranya 92"]
As apple stats, you can use KeyValuePairs to maintain ordered collection of key-value pairs and don’t require the fast key lookup that the Dictionary type provides.
let recordTimes: KeyValuePairs = ["Florence Griffith-Joyner": 10.49,
"Evelyn Ashford": 10.76,
"Evelyn Ashford": 10.79,
"Marlies Gohr": 10.81]
print(recordTimes.first!)
// Prints "("Florence Griffith-Joyner", 10.49)"
Check if it is helpful in your case.
I would like to know how I can make a key of a dictionary have multiple values according to the data that comes to it.
Attached basic example:
var temp = [String: String] ()
temp ["dinningRoom"] = "Table"
temp ["dinningRoom"] = "Chair"
In this case, I always return "Chair", the last one I add, and I need to return all the items that I am adding on the same key.
In this case, the "dinningRoom" key should have two items that are "Table" and "Chair".
You can use Swift Tuples for such scenarios.
//Define you tuple with some name and attribute type
typealias MutipleValue = (firstObject: String, secondObject: String)
var dictionary = [String: MutipleValue]()
dictionary["diningRoom"] = MutipleValue(firstObject: "Chair", secondObject: "Table")
var value = dictionary["diningRoom"]
value?.firstObject
You can declare a dictionary whose value is an array and this can contain the data you want, for example:
var temp = [String: [String]]()
temp["dinningRoom"] = ["Table", "Chair", "Bottle"]
If you want to add a new element you can do it this way:
if temp["dinningRoom"] != nil {
temp["dinningRoom"]!.append("Flower")
} else {
temp["dinningRoom"] = ["Flower"]
}
Now temp["dinningRoom"] contains ["Table", "Chair", "Bottle", "Flower"]
Use Dictionary like this:
var temp = [String: Any]()
temp["dinningRoom"] = ["Table", "Chair"]
If you want to fetch all the elements from dinningRoom. You can use this:
let dinningRoomArray = temp["dinningRoom"] as? [String]
for room in dinningRoomArray{
print(room)
}
It is not compiled code but I mean to say that we can use Any as value instead of String or array of String. When you cast it from Any to [String]
using as? the app can handle the nil value.
I have the following structure:
struct song {
var songnum: Int = 0
var name = "not defined"
var lyrics_wo_chords = NSMutableAttributedString()
var lyrics_w_chords = NSMutableAttributedString()
var favorite = false
}
And I'm trying to make a dictionary var songs = [String: [song]]()
where the the String is the name of the Songbook and the [song]
is an array of structures called song that hold the individual structure members
I've tried this songs["SongBook name"] = song.self as? [song] to add a new Key to the Dictionary. But otherwise, i have no idea how i would initialize it.
Also, when i append the array of the Key:
songs["SongBook name"]?.append(song(
songnum: 1,
name: "Name",
lyrics_o_chords: NSMutableAttributedString(string:"No Chords"),
lyrics_w_chords: NSMutableAttributedString(string: "With Chords"),
favorite:
false))`
the dictionary returned is nil
Any help would be much appreciated, thank you
Your value in your dictionary is an array of song (that is [song]), so you need to put [ ] around your value to make it into an array of song:
songs["SongBook name"] = [song(
songnum: 1,
name: "Name",
lyrics_wo_chords: NSMutableAttributedString(string:"No Chords"),
lyrics_w_chords: NSMutableAttributedString(string: "With Chords"),
favorite: false)
]
Structure and class names should be capitalized, so use Song instead of song when defining your structure.
I've tried the following in a Playground:
var d1 = [String: [String]]()
d1["a"] = [String]()
var a1 = d1["a"]!
a1.append("s1")
println(d1)
The output is: [a: []]
I was hoping for: [a: ["s1"]]
What would be the right way to mutate an array in a dictionary?
In swift, structures are copied by value when they get assigned to a new variable. So, when you assign a1 to the value in the dictionary it actually creates a copy. Here's the line I'm talking about:
var a1 = d1["a"]!
Once that line gets called, there are actually two lists: the list referred to by d1["a"] and the list referred to by a1. So, only the second list gets modified when you call the following line:
a1.append("s1")
When you do a print, you're printing the first list (stored as the key "a" in dictionary d1). Here are two solutions that you could use to get the expected result.
Option1: Append directly to the array inside d1.
var d1 = [String : [String]]()
d1["a"] = [String]()
d1["a"]?.append("s1")
println(d1)
Option 2: Append to a copied array and assign that value to "a" in d1.
var d1 = [String : [String]]()
d1["a"] = [String]()
var a1 = d1["a"]!
a1.append("s1")
d1["a"] = a1
println(d1)
The first solution is more performant, since it doesn't create a temporary copy of the list.
Extending the excellent answer of #jfocht here is
Option 3: Append within function where array is passed by reference
func myAdd(s : String, inout arr : [String]?) {
if arr == nil
{
arr = [String]()
}
arr?.append(s)
}
var d1 = [String : [String]]()
myAdd("s1", &d1["a"])
myAdd("s2", &d1["b"])
println(d1) // [ b: [s2], a: [s1]]
Added some sugar in the sense that it actually creates a new array if given a dictionary key with no arrays attached currently.
Swift Array and Dictionary are not an objects like NSArray and NSDictionary. They are struct. So by doing var a1 = d1["a"] would be like doing var a = point.x and then change a but of course the point.x will not change.
So by doing this instead:
d1["a"] = []
d1["a"]!.append("")
Would be like doing point.x = 10
you need to set a new value for key "a" inside your dictionary.
Which means:
d1["a"] = a1
Would like to add John together with Peter in this combination:
var myData0: [String: String] = ["Item": "Milk", "Description": "Milk is white", "DrinksMilk": "Peter"]
myData0["DrinksMilk"] = "John"
println(myData0)
Println gives only John back instead Peter AND John. Is there a way to add John without overwriting Peter?
If you want to keep a string value of dictionary, you can do like that
var myData0: [String: String] = ["Item": "Milk", "Description": "Milk is white", "DrinksMilk": "Peter"]
myData0["DrinksMilk"] = myData0["DrinksMilk"]! + ", John"
println(myData0)
If not, you can change the type of dictionary value to AnyObject like that :
var myData0: [String: AnyObject] = ["Item": "Milk", "Description": "Milk is white", "DrinksMilk": "Peter"]
myData0["DrinksMilk"] = [myData0["DrinksMilk"]!, "John"]
println(myData0)
It appears that you are attempting to encode a data type into a dictionary. A better approach, not knowing anything more about your specific problem, is to define a class for this:
class Drink {
var name:String
var desc:String
var drinkers:[Person]
// ...
func addDrinker (person:Person) {
drinkers.append(person)
}
}
You've declared your dictionary to hold values of type String but, as you describe, now you want the dictionary values to be String or Array. The common type of these type value types is Any (it can be AnyObject if you've imported Foundation; but that is a Swift anomaly). You will then need to 'fight' the type system to coerce the "DrinksMilk" field as a modifiable array and to add "John".
// First extract `"DrinksMilk"` and force it to a mutating array:
var drinkers:[String] = myData0["DrinksMilk"]! as [String]
// Add the new drinker
drinkers.append("John")
// Reassign back into data
myData0["DrinksMilk"] = drinkers