0 votes
by (1.1k points)
edited by
I'm in doubt, I think I'm starting to tread on complex data structures. So I wonder if this is possible in twine or I would need to try in javascript.

Example: if a couple has a child it would be an addition of an object, a person, to that array, if they have another child it is more an object.

Note: And how to use and access those objects... I would like to know how to do this in js as well.

2 Answers

0 votes
by (44.7k points)
selected by
 
Best answer

Basically, you just add generic objects to the array the same as you would any other array value.  For example:

<<set $someArray = [ { name: "Object1", ID: 1 }, { name: "Object2", ID: 2 } ]>>
<<set $someArray.push( { name: "Object3", ID: 3, xyz: "ABC" } )>>

And then you could access them like this:

<<print $someArray[0].name>>

and that would display "Object1", since that's the value of .name on the object at index 0 of the array.

You can also have objects which contain other objects like this:

<<set $someObject = { Object1: { ID: 1, val: "example" }, Object2: { ID: 2 } }>>
<<set $someObject.Object3 = { ID: 3, xyz: "ABC" }>>
<<set $someObject["Object number four"] = { ID: 4, abc: "XYZ" }>>

And then you could access them like this:

<<print $someObject.Object1.ID>>
<<set _name = "Object2">>
<<print $someObject[_name].ID>>

The first line would display 1 and the last line would display 2.

It works exactly the same in JavaScript, except you need to change the "$" part into "State.variables." and/or the "_" part into "State.temporary.".  So if you wanted a pop-up alert that displayed the value the same way the last line above did, you'd do:

alert(State.variables.someObject[State.temporary.name].ID);

Oh, and you may have guessed based on the above, but if you want arrays within a generic object, then you'd just do something like this:

<<set $someObject = { someArray: [10, 21, 32, 43] }>>

and you could access it like this:

<<print $someObject.someArray[2]>>

and that would display 32.

Hope that helps!  :-)

P.S. Technically speaking, arrays are also objects, they're just a specific kind of object.

0 votes
by (159k points)

Due to how the History system works it is generally a good idea to define related object types once, and then sore a copy that object's key anywhere else that that object needs to be referenced.

The following uses a String property named married to store the key of the partner, and an Array property named children to store the list of offspring keys.

<<set $people to {}>>

<<set $people["jane"] to {
	given: "Jane",
	family: "Doe",
	age: 24,
	married: "",
	children: []
}>>

<<set $people["john"] to {
	given: "John",
	family: "Smith",
	age: 25,
	married: "",
	children: []
}>>

There are two people named <<fullname "jane">> and <<fullname "john">>

Jane and John meet and decide to get married.
<<set $people["jane"].married = "john">>\
<<set $people["john"].married = "jane">>\
Jane is married to <<given $people["jane"].married>>
John is married to <<given $people["john"].married>>

Jane and John have a child named Jill.
<<silently>>
	<<set $people["jill"] to {
		given: "Jill",
		family: "Smith",
		age: 1,
		married: "",
		children: []
	}>>
	<<set $people["jane"].children.push("jill")>>
	<<set $people["john"].children.push("jill")>>
<</silently>>\
<<family "jane">>

Jane and John have a 2nd child named Jimmy.
<<silently>>
	<<set $people["jimmy"] to {
		given: "Jimmy",
		family: "Smith",
		age: 1,
		married: "",
		children: []
	}>>
	<<set $people["jane"].children.push("jimmy")>>
	<<set $people["john"].children.push("jimmy")>>
<</silently>>\
<<family "jane">>


note: The above example relies on the following Widgets.

<<widget "fullname">><<nobr>>
	/* Check if a key was passed to the widget. */
	<<if $args.length > 0>>
		<<set _key to $args[0]>>
		/* Check if a person with that key has been defined. */
		<<if _key in $people>>
			<<set _person to $people[_key]>>
			/* note: Ideally should check if person has 'given' and 'family' properties. */
			<<print _person.given + " " + _person.family>>
		<</if>>
	<</if>>
<</nobr>><</widget>>

<<widget "given">><<nobr>>
	/* Check if a key was passed to the widget. */
	<<if $args.length > 0>>
		<<set _key to $args[0]>>
		/* Check if a person with that key has been defined. */
		<<if _key in $people>>
			/* note: Ideally should check if person has 'given' and 'family' properties. */
			<<print $people[_key].given>>
		<</if>>
	<</if>>
<</nobr>><</widget>>

<<widget "family">><<nobr>>
	/* Check if a key was passed to the widget. */
	<<if $args.length > 0>>
		<<set _key to $args[0]>>
		<<set _description to "">>
		/* Check if a person with that key has been defined. */
		<<if _key in $people>>
			<<set _person to $people[_key]>>
			/* note: Ideally should check if all the relevant properties exist. */
			<<set _description += _person.given>>
			<<if _person.married>>
				<<set _description += " has a partner named " + $people[_person.married].given>>
			<</if>>
			<<if _person.children.length > 0>>
				<<set _description += " 	and " + _person.children.length + " offspring named">>
				<<for _i = 0; _i < _person.children.length; _i++>>
					<<if _i > 0>>
						<<set _description += ",">>
					<</if>>
					<<set _description += " " + $people[_person.children[_i]].given>>
				<</for>>
			<</if>>
		<</if>>
		<<print _description>>
	<</if>>
<</nobr>><</widget>>


 

...