Understanding GameMonkey Script Mixed Arrays - scripting-language

I was just reading some introductory stuff from GameMonkey Script on https://www.gamedev.net/articles/programming/engines-and-middleware/introduction-to-gamemonkey-script-r3297/ and when they were explaining about Mixed Arrays they say that you can access the elements using and index or a key depending on how the value was declared, so for example if i have the next array
myMixedArray = table( 1, 3, 4, KeyV = "Test", 33);
then i can access 1, 2, 4 and 33 using the next indices 0, 1, 2, 3 and
to access "Test" i'll do it like this
myMixedArray["KeyV"] <- ("Test")
now according with the following image that you can find in the above link
The number expected to be at myTest[3] is 7, but that would mean that both regular values and key-val elements are not really separated in the array.
If not then why would 7 be at the index 3 of the array?

While you can treat a gm Table as an Array or Map, you can't effectively do both at the same time.
Internally, the Table is just a hash table, and your index access method is a bit like an iterator.
In your example, because value "Test" is assigned to key 'KeyV', it messes up the otherwise contiguous index order.
Hopefully that gives you an idea of the cause. Try iterating a table with no 'keys' and again with all key value pairs. Observe the different behavior.
If you are serious about arrays, you may be better off using a binding to create an Array type with the behavior you want. GM source has an example of an array container.

Related

Creating a limited count array of custom type

I am creating array of Promises of type [MSGraphScheduleInformation?]. I want to limit the array count to 4, but the repeating param in the API is throwing errors. Below is my code:
For infinite array count the code looks like this:
var array = [Promise<[MSGraphScheduleInformation?]>] // This works
For array with limited count:
var array = [Promise<[MSGraphScheduleInformation?]>](repeating: Promise<[MSGraphScheduleInformation?]>, count: 4) // Throws error
Error I get with above line is - Cannot convert value of type 'Promise<[MSGraphScheduleInformation?]>.Type' to expected argument type 'Promise<[MSGraphScheduleInformation?]>'
Here is what I want eventually:
[Promise<[MSGraphScheduleInformation?] Object 1,
Promise<[MSGraphScheduleInformation?] Object 2,
Promise<[MSGraphScheduleInformation?] Object 3,
Promise<[MSGraphScheduleInformation?] Object 4]
How do I create an array with count and custom type?
As the error message says, you are passing a Type when an instance of that Type is expected.
The repeating initialiser of Array places the value specified by the repeating parameter into the first count indices of the array.
It does not, as your question implies you think, create an array whose elements are the type specified by the repeating array and is limited in size to count.
You should also note that repeating does not specify an initialiser to be called for each element. It is literally the item that will be placed in each index.
You could say something like
var array = [Promise<[MSGraphScheduleInformation?]>](repeating: Promise<[MSGraphScheduleInformation?]()>, count: 4)
You are now passing an instance of a Promise, but you will end up, with that same instance in the first 4 indices. :
[Promise<[MSGraphScheduleInformation?] Object 1,
Promise<[MSGraphScheduleInformation?] Object 1,
Promise<[MSGraphScheduleInformation?] Object 1,
Promise<[MSGraphScheduleInformation?] Object 1]
(I am ignoring whether Promise<[MSGraphScheduleInformation?]()> is even a valid initialiser).
Finally, count only specifies the initial size of the array. It isn't an upper or lower limit that somehow applies to the life of the array. You can remove and append items just like any array.
If you want to limit the number of items in the array you need to do that in your code.
If you want to pre-populate 4 promises, you can use a simple for loop, but that doesn't make a lot of sense. I don't see how you can create a promise before you know what it is promising; I.E. how the promise will be fulfilled.

Why do I get None for key for first level in firebase realtime base with nested 2 levels

I am trying to iter through childs, but I get None for first key which should be e.g. id of case.
example of code
and this is result of code [None, {'-MaISrSqXnill-8W7sG1': {'datum': '22.5.2021', 'idtip_uplate': '11', 'iduplata': '1', 'novaca': '50', 'predmet': '1'}}]
For some reason he don't see first key
When you use numeric keys (like the 1) in your data, you run the risk that Firebase will try to be helpful and interpret those keys as indexes in an array. So in your data it sees it as an array of size 2, with no element at index 0 and the -M... element at index 1. And that's what the output you print shows.
To prevent Firebase from interpreting the keys as an array, ensure they start with a string value. So prefix them with a short known value, like "key1".
For more on this, also see: Best Practices: Arrays in Firebase.

table size difference. are both examples identical?

tNum={[2]=true , [3]=true,[4]=true, [5]=true ,[6]=true }
#tNum-->0
tNum={}
tNum[2]=true
tNum[3]=true
tNum[4]=true
tNum[5]=true
tNum[6]=true
#tNum-->6
why such a difference in size?
are both examples identical?
Your two tables are semantically identical, but using # on them is ambiguous. Both 0 and 6 are correct lengths. Here's an abridged version of the docs:
The length operator applied on a table returns a border in that table. A border in a table t is any natural number that satisfies the following condition:
(border == 0 or t[border] ~= nil) and t[border + 1] == nil
A table with exactly one border is called a sequence.
When t is not a sequence, #t can return any of its borders. (The exact one depends on details of the internal representation of the table, which in turn can depend on how the table was populated and the memory addresses of its non-numeric keys.)
This is an example of undefined behavior (UB). (That may not be the right word, because the behavior is partially defined. UB in Lua can't launch nuclear weapons, as it can in C.) Undefined behavior is important, because it gives the devs the freedom to choose the fastest possible algorithm without worrying about what happens when a user violates their assumptions.
To find a length, Lua makes, at most, log n guesses instead of looking at every element to find an unambiguous length. For large arrays, this speeds things up a lot.
The issue is that when you define a table as starting at index [2], the length operator breaks because it assumes that tables start at index [1].
The following code works as intended:
tNum = {[1]=false, [2]=true, [3]=true, [4]=true, [5]=true, [6]=true}
#tNum => 6
The odd behaviour is caused because when you initialize an array with tNum={} it initializes by assigning every index to nil, and the first index is [1] (It doesn't actually initialize every value to nil, but it's easier to explain that way).
Conversely, when you initialize an array with tNum={[2]=true} you are explicitly telling the array that tNum[1] does not exist and the array begins at index 2. The length calculation breaks when you do this.
For a more thorough explanation, see this section of the lua wiki near the bottom where it explains:
For those that really want their arrays starting at 0, it is not difficult to write the following:
days = {[0]="Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"}
Now, the first value, "Sunday", is at index 0. That zero does not affect the other fields, but "Monday" naturally goes to index 1, because it is the first list value in the constructor; the other values follow it. Despite this facility, I do not recommend the use of arrays starting at 0 in Lua. Remember that most functions assume that arrays start at index 1, and therefore will not handle such arrays correctly.
The Length operator assumes your array will begin at index [1], and since it does not, it doesn't work correctly.
I hope this was helpful, good luck with your code!

Get documents by querying over an array

I have an array of ids. Now I want to get all the documents corresponding to the ids inside that array from a collection.
Is there any command by which I can achieve this?
I don't want to run a loop over that array and query for every element of the array.
Assume the array is
id = [1,2,3,4]
The collection is Scores, which has the field id among other fields.
I'm looking for something like Scores.find(..)
In ActiveRecord, the following query works as expected
Scores.find([1, 2, 3, 4])
Depending on the MongoDB adapter you use, it may work as well. According to this documentation, the same syntax is also supported in Mongoid.
Otherwise, you can generally use
Scores.where(id: [1, 2, 3, 4])
that will return a collection of records matching the given IDs.

What's the difference between arrays and hashes?

What's the difference between arrays and hashes in Ruby?
From Ruby-Doc:
Arrays are ordered, integer-indexed collections of any object. Array indexing starts at 0, as in C or Java. A negative index is assumed to be relative to the end of the array—that is, an index of -1 indicates the last element of the array, -2 is the next to last element in the array, and so on. Look here for more.
A Hash is a collection of key-value pairs. It is similar to an Array, except that indexing is done via arbitrary keys of any object type, not an integer index. Hashes enumerate their values in the order that the corresponding keys were inserted.
Hashes have a default value that is returned when accessing keys that do not exist in the hash. By default, that value is nil. Look here for more.
Arrays:
Arrays are used to store collections of data. Each object in an array has an unique key assigned to it. We can access any object in the array using this unique key. The positions in an array starts from " 0 ". The first element is located at " 0 ", the second at 1st position etc.
Example:
Try the following in - irb.
bikes = Array.new
bikes = %w[Bajaj-Pulsar, Honda-Unicorn, TVS-Apache, Yamaha, Suzuki]
You have added 4 elements in the array.
puts bikes[3]
Yamaha,
Add a new element to position 5.
bikes[5] = "Hardly Davidson"
Hashes:
Like arrays, Hashes are also used to store data. Hashes points an object to another object. Consider of assigning a certain "meaning" to a string. Each time you refer that string, it refers its "meaning".
Example:
bikes = Hash.new
bikes = {
'Bajaj' => 'Pulsar 220, Pulsar 200, Pulsar 180 and Pulsar 150',
'Honda' => 'Unicorn, Shine and Splendor',
'TVS' => 'Apache, Star City, and Victor'
}
Try this now:
bikes['Bajaj']
You get => "Pulsar 220, Pulsar 200, Pulsar 180 and Pulsar 150"
An array is an ordered list of things: a, b, c, d
A hash is a collection of key/value pairs: john has a peugeot, bob has a renault, adam has a ford.
The two terms get "hashed" together these days. I think this is how it goes:
A "hash" will have key -> value pairs:
(top -> tshirt, bottom -> shorts, feet -> shoes)
And an "array" will typically have an index:
([0]tshirt, [1]shorts, [2]shoes)
But, right or wrong, you'll see things with key -> value pairs called "arrays", too.
I think the difference depends mainly on when and how you want to use them. You won't get into much trouble calling an array a hash, or vice versa, but you should know the difference.

Resources