Empty Array Vs Dictionary - arrays

I am just learning Swift and found the concept of Empty Array and Empty Dictionary. I could not dig it down with the simple examples, when to choose it and what are the benefits? Your help would be appreciated.
let emptyArray = [String]()
let emptyDictionary = [String: Float]()
If the constant can be empty then why to use array?

There is nothing to "dig down". An empty thing is just a thing that is empty. Emptiness has no effect on the thingness of a thing. For example:
An empty honey jar is a jar with no honey in it.
An empty bank account is a bank account with no money in it.
An empty string is a string with no characters in it.
An empty array is an array with no elements in it.
An empty dictionary is a dictionary with no key-value pairs in it.
The emptiness of a string does not make the string less of a string; it just happens to be empty. The emptiness of a bank account does not make the bank account less of a bank account. You do not say: how do I choose between between an empty bank account and an empty string? So you do not say: how do I choose between an empty array and an empty dictionary.
So if you don't understand the difference between an array and a dictionary, that is one thing. But the use of "empty" in your question adds nothing whatever to the mix.

It just depends on what you're trying to do. These variables don't just exist in isolation. If they did, they would be useless and you should remove them.
Are you calling an API that requires an array? Well then you would pass it an array.
Are you calling an API that requires a dictionary? Well then you would pass it a dictionary.

Dictionary is an unordered structure of data. Data is accessed by a key-value.
Array is an ordered structure of data. Data is accessed by location.
dict["aKey"] = CGFloat(1)
array.append("Thursday")
The dictionary grows by adding keys and assigning value.
The array grows by appending value to the end.

Related

Firebase: Storing multiple strings inside an array of the same data

I'm making a scheduling app, and storing all the scheduled things in firebase with arrays. When I try to schedule something with the same string value, it fails and doesn't add it to the array. I don't know if this is something in swift I can edit, or if it's a firebase setting.
If it's something in swift, here's the code updating the array:
doc.updateData([
"Instructor": FieldValue.arrayUnion(["\(scheduleinstructor)"])
])
If it's something in firebase, could someone please explain a way around this or a simple fix I overlooked?
According to the documentation on adding items to an array:
arrayUnion() adds elements to an array but only elements not already present
So the fact that the duplicate entry is not added is by design. If you want to allow that, you'll have to:
Read the document with the array from the databae.
Extract the array from the document into your application code.
Add the item to the array.
Write the entire modified array back to the database.

How can I filter large amount of JSON in OpenRefine?

I'm using OpenRefine to pull in information on publisher policies using the Sherpa Romeo API (Sherpa Romeo is a site that aggregates publisher policies). I've got that.
Now I need to parse the returned JSON so that those with certain pieces of information remain. The results I'm interested in need to include the following:
'any_website',
'any_repository',
'institutional_repository',
'non_commercial_institutional_repository',
'non_commercial_repository'
These pieces on information all fall under an array called "permitted_oa". For some reason, I can't even work out how to just pull out that array. I've tried writing grel expressions such as
value.parseJson().items.permitted_oa
but it never reutrns anything.
I wish I could share the JSON but it's too big.
I can see a couple of issues here.
Firstly the Sherpa API response items is an array (i.e. a list of things). When you have an array in the JSON, you either have to select a particular item from the array, or you have to explicitly work through the list of things in the array (aka iterate across the array) in your GREL. If you've previously worked with arrays in GREL you'll be familiar with this, but if you haven't
value.parseJson().items[0] -> first item in the array
value.parseJson().items[1] -> second item in the array
value.parseJson().items[2] -> third item in the array etc. etc.
If you know there is only ever going to be a single item in the array then you can safely use value.parseJson().items[0]
However, if you don't know how many items will be in the array and you are interested in them all, you will have to iterate over the array using a GREL control such as "forEach":
forEach(value.parseJson().items, v, v)
is a way of iterating over the array - each time the GREL finds an item in the array, it will assign it to a variable "v" and then you can do a further operation on that value using "v" as you would usually use "value" (see https://docs.openrefine.org/manual/grel#foreache1-v-e2 for an example of using forEach on an array)
Another possibility is to use join on the array. This will join all the things in an array into a string.
value.parseJson().items.join("|")
It looks like the Sherpa JSON uses Arrays liberally so you may find more arrays you have to deal with to get to the values you want.
Secondly, in the JSON you pasted "oa_permitted" isn't directly in the "item" but in another array called "publisher_policy" - so you'll need to navigate that as well. So:
value.parseJson().items[0].publisher_policy[0].permitted_oa[0]
would get you the first permitted_oa object in the first publisher_policy in the first item in the items array. If you wanted to (for example) get a list of locations from the JSON you have pasted you could use:
value.parseJson().items[0].publisher_policy[0].permitted_oa[0].location.location.join("|")
Which will give you a pipe ("|") separated list of locations based on the assumption there is only a single item, single publisher_policy and singe permitted_oa - which is true in the case of the JSON you've supplied here (but might not always be true)

Firebase Firestore: Append/Remove items from document array

I am trying to append/remove items from an array inside of a Firestore Document but every time the entire array is replaced instead of the new value being appended. I have tried both of the following:
batch.setData(["favorites": [user.uid]], forDocument: bookRef, options: SetOptions.merge())
batch.updateData(["favorites": [user.uid]], forDocument: bookRef)
I know that instead of an array I can use an object/dictionary but that would mean storing additional data that is irrelevant (such as the key), all I need is the ID's stored inside the array. Is this something that is currently possible in Firestore?
Update elements in an array
If your document contains an array field, you can use arrayUnion() and arrayRemove() to add and remove elements. arrayUnion() adds elements to an array but only elements not already present. arrayRemove() removes all instances of each given element.
let washingtonRef = db.collection("cities").document("DC")
// Atomically add a new region to the "regions" array field.
washingtonRef.updateData([
"regions": FieldValue.arrayUnion(["greater_virginia"])
])
// Atomically remove a region from the "regions" array field.
washingtonRef.updateData([
"regions": FieldValue.arrayRemove(["east_coast"])
])
See documentation here
Actually, nowadays it is possible. With latest updates db.collection.updateData
method actually appends new item to array instead of replacing it.
Example usage can be found in Firebase documentation.
If you need to do it manually, you can use
FieldValue.arrayUnion([user.uid])
Nope. This isn't possible.
Arrays tend to be problematic in an environment like Cloud Firestore where many clients could theoretically append or remove elements from an array at the same time -- if instructions arrive in a slightly different order, you could end up with out-of-bounds errors, corrupted data, or just a really bad time. So you either need to use a dictionary (where you can specify individual keys) or replace the entire array.

Wrong length of array, empty row on dom-repeat in Polymer

I'm trying to retrieve Firebase data with Polymer Fire. When I look in the console it's returning two objects, however the length of the array is three. When I'm trying to execute a dom-repeat I'm successfully printing two filled in rows but also one empty row. How is this possible?
Firebase stores data as associative arrays, essentially a dictionary of key/value pairs.
That means that in order to deal with arrays, it converts an array to a dictionary when you store it and then back to an actual array when you read it. Here you are getting bitten by the SDK converting your non-array into an array by padding it with a leading element.
If you don't want the SDK to do this conversion, the easiest way is to store the items with a non-numeric key, e.g. "item1", "item2".
Read more about how Firebase deals with arrays in this classic blog post: https://firebase.googleblog.com/2014/04/best-practices-arrays-in-firebase.html

How do I filter an array based on object's property with multiple OR statements

The question was difficult to put into words, but here is my situation. I have several Monster objects in an array called monsters. Each monster has a name property which is a String.
I have a second array called monsterNames, which contains several monster names (as Strings).
I want to be able to filter all the monster objects in monsters array based on whether the individual monster object's name property appears in the monsterNames array.
I have been looking at solutions so far I have only found solutions that filter based on a single condition, which allows me to only filter based on a single monster name in the monsterNames array. Can anybody help me find an efficient solution to this?
You could do something like:
let monsters: [Monster] = ...
let monsterNames: [String] = ...
let filteredMonsters = monsters.filter { monsterNames.contains($0.name) }
This doesn't perform all that well, since it will go over the names array up to n times for each monster, but if your names arrays is small, this won't be a problem.

Resources