Help:Extension:Arrays

From mediawiki.org
Jump to navigation Jump to search

The Arrays extension adds a number of parser functions to define, manipulate, and display arrays of data.

Introduction[edit]

Arrays are useful for storing and manipulating lists of data, for example to allow an editor to provide a list of items to a template to be automatically linked, using only a single template parameter for any number of items, instead of requiring one parameter for each item.

Because of how the array functions work, each array, once created, constitutes a piece of global state for the current page, able to be accessed by array functions from anywhere else on the page, similar to Extension:Variables . Extension:Page Forms features two parser functions (#arraymap and #arraymaptemplate) that allow for simple array definition and printing, without creating any global state, and Lua modules can be used to manipulate lists of data arbitrarily without requiring global state.

Because the array functions create global state, once an array is defined, it can be displayed or modified anywhere else on the page. To avoid confusion, most of the code examples on this page will explicitly define the array they use; this means that in some cases, the same array name will be reused, and multiple code examples might each define the same array with the exact same contents. In actual usage, a given array would only be defined once, and then only redefined if the original value is no longer needed but a modified value is (for example, if only a sorted copy of the array is needed, or a copy of the array with duplicate items removed).

#arraydefine[edit]

#arraydefine is the basic method to define a new array. At minimum it requires the name of the array to be defined, and the value(s) to be stored in the array; in addition, a delimiter and certain options can be specified.

{{ #arraydefine: array name | array values | delimiter (defaults to comma) | options }}

The array name can be any string; generally it should be a short, descriptive name, though care should be taken not to select a name that might be confused with other features. For example, fruits might be a good array name; array probably is not. Optionally, the name can be prefixed or suffixed with a special character to help visually distinguish it from surrounding text; for example, @fruits or $fruits.

The delimiter defaults to a comma (,), but any string (or no string) can be specified, as well as a regex fragment. Whitespace around the delimiter is ignored.

The array values are a list of strings separated by the delimiter.

{{ #arraydefine: fruits | apple, orange , banana,grape }} creates an array named "fruits", with the items "apple", "orange", "banana", and "grape".
{{ #arraydefine: cities | Berlin, Germany;Paris, France ;Montreal, Canada | ; }} creates an array named "cities", with the items "Berlin, Germany", "Paris, France", and "Montreal, Canada".
Warning Warning: A defined but empty delimiter does not default to a comma! It instead stores the entire input string as a single item. Consider two arrays:
The first array is defined as {{ #arraydefine: fruits | apple, orange , banana,grape }}. {{ #arraysize: fruits }} will print 4, and {{ #arrayprint: fruits }} will print apple, orange, banana, grape.
The second array is defined as {{ #arraydefine: colors | red, blue , green,yellow | }}. {{ #arraysize: colors }} will print 1, and {{ #arrayprint: colors }} will print red, blue , green,yellow (note the preserved whitespace around the commas).


A regex fragment can be used for the delimiter, indicated by //.

{{ #arraydefine: days | Saturday, Sunday, Monday; Tuesday, Wednesday, Thursday, Friday | /[,;]/ }} defines an array named "days" where items can be separated by either a comma (,) or a semicolon (;). In this example, the semicolon is used to group the input into days named after celestial bodies and days named after Norse gods, though the array itself doesn't keep that distinction.

A regex delimiter can also be used to split input on newlines, or to split individual characters of the input.

{{ #arraydefine: seasons | 
Spring
Summer
Fall
Winter
| /\n/ }}
defines an array named "seasons" where each item is placed on its own line. Note that by default, printing this array will still result in the items being separated by commas.
{{ #arraydefine: digits | 0123456789 | // | unique }} defines an array named "digits", containing the digits from 0 to 9 as separate items.
Warning Warning: #arraydefine with a regex delimiter is not multi-byte-character-safe! If an affected array is printed, the content area of the page will be rendered blank, and if #arraysize is used on the array (and the array is not printed), unexpected sizes may be returned. This is because the regex delimiter is applied at the byte level, instead of the codepoint level. See "Multi-byte characters are not safe".
{{ #arraydefine: dashes | -,–,— }} behaves as expected: {{ #arraysize: dashes }} prints 3, and {{ #arrayprint: dashes }} prints -, –, —.
{{ #arraydefine: dashes | -,–,— | , }} and {{ #arraydefine: dashes | -,–,— | /,/ }} also behave as expected.
{{ #arraydefine: dashes | -–— | // }}, however, does not: {{ #arraysize: dashes }} prints 9, and {{ #arrayprint: dashes }} causes the content area to be blank.
If the only multi-byte characters in the array input are defined as delimiters, the array can be printed normally, but this should not be relied on because of how easily a different multi-byte character could be introduced (including accidentally), causing the entire page to render blank.
Warning Warning: Using a regex delimiter of // to split the array input into individual characters will cause blank items to be added at the beginning and end of the array.
{{ #arraydefine: digits | 0123456789 | // }} results in an array where {{ #arraysize: digits }} prints 12 (instead of the expected 10), and {{ #arrayprint: digits }} prints , 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,.

Unfortunately there is no good way to remove these empty items. One option is #arrayunique (or the unique option on #arraydefine), but this will also remove duplicate items, which may not be desired. To avoid this, #arrayslice and #expr can be used to resave the array without the empty first and last elements, #arraysearcharray can resave the array without any empty elements, or a more complicated regex can be used to avoid selecting empty items:

{{ #arraydefine: digits | 0123456789 | // }}{{ #arrayslice: digits | digits | 1 | {{ #expr: {{ #arraysize: digits }} - 2 }} }}{{ #arraysize: digits }}: {{ #arrayprint: digits }} gives 10: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
{{ #arraydefine: digits | 0123456789 | // }}{{ #arraysearcharray: digits | digits | /.+/ }}{{ #arraysize: digits }}: {{ $arrayprint: digits }} gives 10: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
{{ #arraydefine: digits | 0123456789 | /(?<=\w)(?=\w)/ }}{{ #arraysize: digits }}: {{ #arrayprint: digits }} also gives 10: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.