Array functions - ThePix/QuestJS GitHub Wiki

There are broadly three types of array functions available to authors. Those that are provided by Quest belong to the array object. JavaScript also has some functions that are associated with the Array object, and others that belong to the array itself.

Arrays can be made by putting the values inside square brackets. This example creates an array with four elements.

const a = ['one' ,'two', 'three', 'four']

Arrays can contain any type; numbers, strings, other arrays, etc. and any particular array can contain a mixture.

Arrays will not necessarily be saved when the user saves the game. Quest will look at the first element, and if that is not a string or number it will not save it. If it is a string or number it will assume every element is of the same type, and will attempt to save it on that basis - and if that is not the case it will throw an error.

Quest 6 array functions

array.subtract(a, b)

Returns a new array, as a, but excluding any member that is in b.

array.compare(a, b)

Returns true if each element in a matches the corresponding element in b, in the same order. This is not quite the same as the arrays being equal. If the example below, a and c are the same, so a === c will be true. However, a and b are not the same (they point to different memory locations), so a === b is false. They do all contain the same elements, so this function will return true for all of them.

const a = ['one' ,'two', 'three', 'four']
const b = ['one' ,'two', 'three', 'four']
const c = a

array.compareUnordered(a, b)

Returns true if each element in a matches the elements in b, but not necessarily in the same order (assumes each element is unique; repeated elements may give spurious results).

array.filterByAttribute(a, name, value)

Returns a new array based on a, but including only those objects for which the attribute name is equal to value. To filter for objects that do not have the attribute you can filter for the value undefined (or just omit the third parameter).

array.remove(a, el)

Removes the element el from the array, a. Unlike array.subtract, no new array is created; the original array is modified, and nothing is returned. You can remove any number of elements in one go.

array.remove(myArray, el1, el2, el3)

array.atts(a, name)

Returns a new array based on a, by extracting the value of the given attribute (which defaults to "name" if not specified). If an element has a function for the given attribute, the function is run and the return value used (undefined if none is returned). If an element does not have the attribute, undefined is used.

If you have an array of objects or exits, you can use this to get an array of names.

array.next(a, el, circular)

Returns the next element after el from the array, a. If el is present more than once, it goes with the first. If el is the last element, and circular is true it return the first element or false otherwise.

array.nextFlagged(a, el, att, circular)

Returns the next element after el from the array, a, for which the attribute, att, is true. If el is present more than once, it goes with the first. If el is the last element, and circular is true it return the first element and false otherwise.

array.clone(a, options)

Returns a copy of the given array. Members of the array are not themselves cloned. If in the options you set "compress" to true, repeated elements will be omitted in the copy. If you set "reverse" to true, the order will be reversed. If "value" is set, the value of that attribute is used, and if "function" then the named attribute will be run and the result added to the array. If "attribute" is set, it will be run if a function, otherwise the value will be used.

array.fromTokens(a, scope, cmdParams)

Given an array of strings, a, this will try to match the strings to the items listed in "scope". It will try to do this greedily, i.e., it will try to match as many of the strings to a single item that is can.

The "cmdParams" parameter is optional. If used it should be a dictionary that can have an "attName" attribute to have the function favour items with this attribute, or an "items" attribute, an array of specific items to favour.

Uses parser.findInList.

array.value(a, index, opt)

Gets the value from an array. Generally this is just the same as a[index], but the difference is what happens if index is out of range. The parameter "opt" should be a string, with one of these values

Value Returns
none Empty string
end Last element
start First element
wrap Wraps

Wraps means that that the index cycles back to the beginning, and the returned element is the one at index % a.length

JavaScript Array Functions

Array.isArray(o)

Returns true if the given thing is an array.

Removing duplicates

If you have an array, a, and want to remove duplicate entries, so each entry is unique, you can do this:

const uniq = [...new Set(a)]

This uses some pretty esoteric JavaScript compared to the rest of QuestJS (even behind the scenes), but is creating a Set object from the array, which is a built-in list that disallows duplicates. The three dots are the "spread" operator, which converts the Set back to an array.

JavaScript functions on arrays

Rather than pass the array as a parameter to the function, the function belongs to the array (so is written a.func). The first example gives more details.

a.find(func)

Say we have an array, a, and we want to find a certain element, we can use this function, which itself takes a function as a parameter. This secondary function will be passed each element in turn, and should return true if the element is suitable. The find function will return the first member of the array that fits, or false if none do.

Here is an example that looks for a string that starts with a "t".

const a = ['one' ,'two', 'three', 'four']
const func = function(el) { return el.startsWith('t') }
const result = a.find(func)

It is common to combine the last two lines:

const a = ['one' ,'two', 'three', 'four']
const result = a.find(function(el) { return el.startsWith('t') })

And indeed, it is even more common to use a special shortcut notation with =>:

const a = ['one' ,'two', 'three', 'four']
const result = a.find(el => el.startsWith('t'))

a.findIndex(func)

As find, but returns the index of the element, rather than the element itself.

a.map(func)

Returns a new array where each element of the original has been transformed by the given function. Say you want to get the names of several objects, you could do this. The first version gets the identifier name, the second the name the user would see.

const result = a.map(el => el.name)
const result = a.map(el => lang.getName(el, {article:DEFINITE}))

a.sort(func)

Returns a new array where each element of the original has been sorted by the given function. Say you want to have several objects listed in aphabetical order, based on their alias.

// sort the list
const sortedList = unsortedList.sort(function(a, b) {
  var nameA = a.name.toUpperCase()
  var nameB = b.name.toUpperCase()
  return (nameA < nameB ? -1 : 1)
})

a.filter(func)

Returns a new array containing only the element of the original that return true for the given function. Say you want to get a list of worn items, you could do this.

const result = a.filter(el => el.worn)

a.includes(el)

Returns true if the array contains the given element.

a.some(func), a.every(func)

Returns true if at least one or if every element of array returns true for the given function. In the example below, result1 will be true, as there are some elements that start with "t", but result2 will be false as not every element does.

const a = ['one' ,'two', 'three', 'four']
const result1 = a.some(el => el.startsWith('t'))
const result2 = a.every(el => el.startsWith('t'))

pop, push, shift, unshift

JavaScript has four functions for adding and removing elements from the start and end of an array.

Where Add Remove
Start unshift shift
End push pop
a.push('Hat')
const s = a.pop()