0 votes
by (160 points)

I have this basic code below in a Passage named Test, and added the forest tag within the passage editor:

Direct property reference test:
<<print Story.get("Test").tags>>

Passage lookup test:
<<set $list to Story.lookup("tags", "forest")>>
<<print $list.count()>>
<<for $i to 0; $i lt $list.length; $i++>>
	<<set $title to $list[$i].title>>
	[[$title]]
<</for>>

When I run it the output is:
Direct property reference test:
forest

Passage lookup test:

0

$title

 

I would expect Story.lookup to return an array of size 1.  Any ideas why not?  Using the windows Twine editor.

Thanks for any help!

1 Answer

0 votes
by (160 points)

Never mind, I realized the Sugarcube array documentation didn't include length and I assumed count was the same.  Also had some other issues.  This works as expected:
 

Direct property reference test:
<<print Story.get("Test").tags>>

Passage lookup test:
<<set $list to Story.lookup("tags", "forest")>>
<<print $list.length >>
<<for $i to 0; $i lt $list.length; $i++>>
	<<print $list[$i].title>>
	<<set $go to $list[$i].title>>
	<<link $go>><</link>>
<</for>>

 

by (68.6k points)
edited by

SugarCube does not include general Array documentation, since SugarCube types are simply JavaScript types and sites like MDN cover JavaScript better than SugarCube's docs ever could.  There is a section for Array methods, however, that's because most of the documented methods are SugarCube extensions, thus cannot be found elsewhere.

Also.  You were using <Array>.count() incorrectly in your initial example.  It counts the number of times the specificed search needle was found within the array.  By not passing it a needle, you were counting the undefined value.

Finally.  There's no need for the intermediate step of assigning the passage title to a variable in your second example.  Even if you did need to do so, a temporary variable would be better there; and also for the loop index variable.  For example:

/* Using a temporary variable. */
<<set _go to $list[$i].title>>
<<link _go>><</link>>

/* Backquoting the expression; see the Macro Arguments section of the docs. */
<<link `$list[$i].title`>><</link>>

/* Simply using the link markup. */
[[$list[$i].title]]

 

You might also give the ranged form of the <<for>> macro a try as it allows you to do away with most of the bookkeeping involved with iterating over a collection.  For example:

/* Link markup. */
<<for _passage range $list>>
	<<print _passage.title>>
	[[_passage.title]]
<</for>>

/* <<link>> macro. */
<<for _passage range $list>>
	<<print _passage.title>>
	<<link `_passage.title`>><</link>>
<</for>>

 

PS: If $list is only used as shown in your examples, then it would also be better as a temporary variable.  The basic rule of thumb is that any variable you don't need to persist beyond a single passage should be a a temporary variable rather than a story variable.

In this particular instance, there's actually no need for the intermediary variable at all, you can simply use the call to Story.lookup() within the loop.  For example:

<<for _passage range Story.lookup("tags", "forest")>>
	<<print _passage.title>>
	[[_passage.title]]
<</for>>

 

...