Add new entries to a "complex" dictionary - swift

I have a more "complex" dictionary that I am trying to add new entries to. The dictionary code is as follows:
var users: [[String:Any]] = [
[
"firstName": "Bill",
"lastName": "G"
]
]
I tried adding a new entry with this code:
users[1]["firstName"] = "Steve"
users[1]["lastName"] = "J"
print(users) // fatal error: Array index out of range
But receive "fatal error: Array index out of range" I looked at several examples but all seem to deal with simpler dictionaries. What am I missing?

You need to first create an instance of the dictionary and add it to the array, you can then add key:value pairs to it:
var users: [[String:Any]] = [
[
"firstName": "Bill",
"lastName": "G"
]
]
users.append([String:Any]())
users[1]["firstName"] = "Steve"
users[1]["lastName"] = "J"
print(users) // [["firstName": "Bill", "lastName": "G"], ["firstName": "Steve", "lastName": "J"]]
You can even do it in a single statement like this:
users.append(["firstName": "Steve", "lastName": "J"])
If you don't append a new element on to the array then when you try to reference the next index it will be out of range.

This works in a playground
var users: [[String:Any]] = [
[
"firstName": "Bill",
"lastName": "G"
]
]
users[0]["firstName"] = "Steve"
users[0]["lastName"] = "J"
users
Using index 0, not 1 like you were using which causes the index out of bounds error
Or the more dynamic approach
var users = [[String:AnyObject]]()
let personA = ["Steve":"J"]
let personB = ["Foo":"Z"]
users.append(personA)
users.append(personB)
users

Related

Extract values of dictionary

struct Country {
var translations : [String:String?]? // must be defined as optionals!
}
// example entry
translationsDict = [
"translations": [
"de":"Deutschland",
"en": "germany",
"it": nil
]
]
How can I extract the values "Deutschland" and "germany" into a new array?
result should be:
["germany", "Deutschland"]
Firstly, get a collection of all values of translations, then convert it to an array.
if let collection = translationsDict["translations"]?.values {
let array = Array(collection)
print(array)
}
or
if let array = translationsDict["translations"]?.map({ $0.1 }) {
print(array)
}

How can I append to a specific dictionary within an array of dictionaries in swift?

My data structure:
var defs = [["a":"b","c":"d"],["e":"f","g":"h"]]
I have tried the following:
dict[1]["testKey"] = "testValue"
in an attempt to attain the following:
defs = [["a":"b","c":"d"],["e":"f","g":"h","testKey":"testValue"]]
This doesn't work though. Does anyone have a good solution?
You have a typo in your code (I see you're using dict instead of defs but this works fine:
var defs = [
[
"a": "b",
"c": "d"
],
[
"e": "f",
"g": "h"
]
]
defs[1]["key"] = "value"
print(defs[1]["key"]) // "Optional("value")\n"
var defs = [["a":"b","c":"d"],["e":"f","g":"h"]]
defs[1]["testKey"] = "testValue"
print(defs)
prints:
[["a": "b", "c": "d"], ["e": "f", "testKey": "testValue", "g": "h"]]
The elements contained within the defs array are of type Dictionary, which by definition is unordered. If the order is an issue, you have to use another collection type.

How to query a reference in MongoDB

I have found this tutorial online which is helpful. However it shows an example using an array of two objectIds. How could the query be done if it was one objectId instead of two?
http://www.tutorialspoint.com/mongodb/mongodb_relationships.htm
{
"_id":ObjectId("52ffc33cd85242f436000001"),
"contact": "987654321",
"dob": "01-01-1991",
"name": "Tom Benzamin",
"address_ids": [
ObjectId("52ffc4a5d85242602e000000"), // if this was not an array and just one ObjectId
ObjectId("52ffc4a5d85242602e000001")
]
}
var result = db.users.findOne({"name":"Tom Benzamin"},{"address_ids":1})
var addresses = db.address.find({"_id":{"$in":result["address_ids"]}})
I hope I got it right. So you have elements of this sort:
{
"_id":ObjectId("52ffc33cd85242f436000001"),
...
"address_ids": ObjectId("52ffc4a5d85242602e000000")
}
Your code will look like this:
var result = db.users.findOne({"name":"Tom Benzamin"},{"address_ids":1})
var addresses = db.address.find({"_id": result["address_ids"]})

MongoDB: How to update a compound item of an array ensuring no duplicates

Here below is a hypothetical Users collection where more than one address is allowed:
{
"firstName": "Joe",
"lastName": "Grey",
...
"addresses":
[
{
"name": "Default",
"street": "..."
...
},
{
"name": "Home",
"street": "..."
...
},
{
"name": "Office",
"street": "..."
...
}
]
}
Every address has a name... which should be unique – e.g. there couldn't be two addresses named Default. If I want to update let's say the address at index 1 (Home), how do I ensure the update data does not contain names Default and Office?
I guess a two-steps approach (i.e. find and then update) wouldn't be very correct since data might be updated between the find and the subsequent update operation, isn't?
var renamed = 'Office'; // from user input
var users = getUserMongoCollection();
users.update({_id:userId, 'addresses.name': { $ne : renamed } },
{ $set : { 'addresses.1.name' : renamed } }, function(err){
//all done!
});
Find the record by ID, and only update it if the array doesn't contain the new name.

MongoDB: How to update a complex item of an array with a new complex item

Here below is once again my hypothetical Users collection where more than one address is allowed:
{
"firstName": "Joe",
"lastName": "Grey",
...
"addresses":
[
{
"name": "Default",
"street": "...",
...,
"isDefault": true
},
{
"name": "Home",
"street": "...",
...,
"isDefault": false
},
{
"name": "Office",
"street": "...",
...,
"isDefault": false
}
]
}
Let's suppose I want to update the second address (Home) with the following new item:
{
"name": "New home",
"street": "Ruta del Sol"
},
How do I update the second item of the array with the new item, also considering that the new item might or might not provide all the fields of an address?
In this post Will shown me how to update a field at a given index, ensuring the address name remains unique. Now, instead of updating a single field, I want to update an entire item.
All you need to do is transform new json data for update . Example:
Let us assume you have new Json data with only two fields 'name' and 'isDefault' .
var newData = {"name" : "New Val","isDefault":true};
var updateData = {};
for (key in newData ) {
updateData["addresses.$."+key]=newData[key];
};
db.projectPlan.update({_id:1, 'addresses.name': 'Home'}, {$set:updateData});
var renamed = 'Office'; // from user input
var users = getUserMongoCollection();
var address = {
name: "Office,
street: "Ruta del Sol"
};
users.update({_id:userId },
{ $set : { 'addresses.1' : address } }, function(err){
//all done!
});