Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Using all values from an array in Harlowe

I have an array with a list of passages, and I want to display all of them.
(set: $list to (a: "Pass1", "Pass2"))
(display: $list's 1st)
(display: $list's 2nd)

I would like a generic mechanism that can do this with any arbitrary number of values in the array.

So far I have a (live:) pseudoloop: getting a value, displaying the value, printing the value, increasing an index, printing the next value, stopping the loop when the index increases past the length of the array.

The problem with this approach is that I don't think it has a good performance. It's difficult for me to pinpoint the causes for performance problems in my game (which is way more complex than this), but this is the main mechanism and so I feel this is one of the main problems.

Can you think of any other way that I can achive this? Maybe printing all the values of the array at once and using Javascript to change the separator character?

Comments

  • I'd go with Javascript. If you want them each on a separate line, try:
    (print: $list.join("\n"))
    
  • I hoped there would be a more elegant solution that the thing I finally had to do:
    (print: 
    	"(display: '" + 
    	$list.join("'\)(display: '") +
    	"'\)"
    )
    

    It prints a single (display: and then the elements of the array separated by the closing parenthesis and the following (display: macro, and it ends with a single closing parenthesis.

    But it works as far as I can tell and in more complicated scenarios (with the separator string having more Harlowe macros).

    Sadly, the performance gains are noticeable but not that great. :-/

    Thanks!
  • edited February 2016
    @Menti: If you are going to use that code structure more than once and if you don't mind using a little more Javascript then you could extend the Array like so:

    a. Add the following to your Story Javascript, it adds a new method named prefixedJoin to the Array class.
    // prefixedJoin(prefix, suffix, [seperator])
    //		prefix: string to concatenate to the start of each element.
    //		suffix: string to concatenate to the end of each element.
    //		seperator: optional string to separate each element.
    //
    if (! Array.prototype.prefixedJoin) {
    	Object.defineProperty(Array.prototype, "prefixedJoin", {
    		configurable: true,
    		writable: true,
    		value: function(prefix, suffix, seperator) {
    			"use strict";
    			if (this == null) {
    				throw new TypeError("Array.prototype.prefixedJoin called on null or undefined");
    			}
    			if (this.length === 0) {
    				return '';
    			}
    			if (seperator == null) {
    				seperator = '';
    			}
    			return '' + prefix +
    				this.join('' + suffix + seperator + prefix) +
    				suffix;
    		}
    	});
    }
    
    b. You use the new prefixedJoin method like so:
    (set: $list to (a: "Pass1", "Pass2"))
    
    (print: $list.prefixedJoin('(display: "', '")', '\n'))
    
  • Thanks @greyelf! In my case, I don't need to use the structure often, just a few and known places in my "engine" passages. Anyway your solution is great.
Sign In or Register to comment.