I've been trying to create a personnel database in an object with an option to retrieve random 3 persons/values. I am quite content with repeating the same code three times, since I most probably won't be needing to pull more than 3 values at once, but I just can't get over the fact I have no idea how to make that work in a loop, the way I want it to work.
As far as I can get is this:
<<set $Database = ["Person1", "Person2", "Person3", "Person4"]>>
<<for $i to 0; $i lte 3; $i++>>
<<set $Random = (0, 3)>>
<<set $RetrievedPerson1 = $Database[$Random]>> <--Here is where my problem starts. I have no idea how to format the "Retrieved Person" name the way for the loop to increase the number with each loop iteration. I am guessing it can be done easily, but I couldn't find an answer. I don't even know how to properly formulate the question.
<</for>>
I would appreciate any suggestions.
It also would be good to know how to put an object within an object in Twine and how to recover that values, but I guess I can figure out a way around that.
Sorry for my english.
Comments
So, is this SugarCube 2 or SugarCube 1? Please say SugarCube 2.
I assume what you're trying to articulate is that you want to programmatically create $variable names, which can be done, though it requires slightly deeper knowledge of the inner workings of SugarCube. It would be simpler, though somewhat more cumbersome, to simply switch on the value of your loop index ($i) via the <<if>> macro.
That said, if you're only going to be pulling small numbers of items, why do you need a loop in the first place? You can simply pull the requsite number of members, no need for a loop.
No Loop Examples So, to retrieve three members from $Database, and if duplicates (i.e. the same random value multiple times; which would also be an issue using a loop) are okay, you could simply do something like the following:
If duplicates are not okay, you want unique pulls each time, then the simplest thing you can do is to remove each member as it's chosen. You can achieve this with the <Array>.pluck() method.
For example, if you are setting up $Database every time (i.e. it's okay to remove members from it), then you can do the following:
On the other hand, if $Database is something you setup once (i.e. it's not okay to remove members from it), then you can make a copy and pluck members from that:
Loop Example
Now that I've covered how you should probably do it, here's how you could use a loop to do by programmatically accessing the $variable names: Again, if $Database should not be modified, then pluck from a copy, like so:
You used "object" before to refer to an Array (which is technically true, Arrays are objects), but most of the time when you say "object" we're going to assume you mean Objects (generic objects). So, are you talking about Arrays or Objects?
Here are some examples (no commentary though):
Arrays
Objects
Thanks for this very useful answer.
However, I'm having trouble with either datastructure, or syntax after using the insight I got from your post.
I have a $map variable with locations nested in it, each location being an object containing stuff. I could not set-up $map as an array containing objects, because Twine then says there's an error ("Error: <<set>>: bad evaluation: Unexpected token").
I changed $map to an object, and then it works.
However, I'm trying to build a loop to print all this, location by location, which seems impossible to do with the object structure, unless there's a way to reference each Location object in the Map object by an index value (like an array has), which i'm not sure there is for an object.
Here is my map thingy set up:
And the loop I originally set up when I thought I could nest objects inside arrays:
Is there any solution to this issue (either a way to reference an object's index if there is one, or nesting objects inside an array) ?
For what you're doing, it probably makes more sense to use an object containing objects. A loop to print all of the locations using such a structure could look something like the following:
Assuming that this is for debugging or something, here's a somewhat more nicely formatted version using tables:
This may very well be why it didn't work?
Anywhay, thanks a lot for your code, it works very well and now I just have to understand it ;p
So I have some questions about it :
What does the function Object.keys($variable) do exactly?
What do the pipes | do?
what's |h and |! do?
What do the \ do ?
Put simply, it returns an array of the given object's own property names (a.k.a. keys). Objects consist of key/value pairs. For example: In the case of Object.keys($map), it returns an array of the names of each object you've stored in $map (e.g. tavern and taverncellar).
As I noted with the example, they're part of the table markup. Specifically, the TiddlyWiki table markup (I could have used HTML table markup instead).
SugarCube's markup language (docs: for SugarCube 2.x or for SugarCube 1.x) is based on TiddlyWiki markup, though there are some differences.
It's the line continuation character (see: Line Continuations, for SugarCube 2.x or for SugarCube 1.x).