Array Macros¶
Working with arrays and lists in question control code.
Most PHP array functions are not available
Control code runs against a fixed allowlist. array_push, array_pop,
array_shift, array_unshift, array_slice, array_search,
array_key_exists, array_merge, sort, asort and rsort are not
on it. Earlier versions of this page documented all of them. The engine's
own equivalents are below.
Creating arrays¶
array($value1, $value2, …)¶
$colors = array("red", "green", "blue")
$numbers = array(1, 2, 3, 4, 5)
$person = array("name" => "Alice", "age" => 25)
Bracket shorthand works too
$colors = ["red", "green"] and $person = ["name" => "Alice", "age" => 25]
create the same arrays as array(...). Either form can be passed straight
to a macro, e.g. sumarray([3, 5, 8]).
consecutive($min, $max, $step)¶
A run of evenly spaced values — the engine's range constructor. $step defaults to 1 and may be negative to count down.
$ints = consecutive(1, 10) // 1, 2, 3, … 10
$evens = consecutive(2, 20, 2) // 2, 4, 6, … 20
$down = consecutive(10, 1, -1) // 10, 9, 8, … 1
$tenths = calconarray(consecutive(0, 10), "x/10") // 0, 0.1, 0.2, … 1 exactly
// consecutive(0, 1, 0.1) drifts: its last value is 0.9999999999999999, so == 1 fails
fillarray($value, $n, $start)¶
$n copies of $value, keyed from $start (default 0). If $n is itself an array, its entries become the keys.
$zeros = fillarray(0, 5) // five 0s
$blanks = fillarray("", array("a", "b")) // "a" => "", "b" => ""
listtoarray($list) and stringtoarray($str)¶
listtoarray splits a comma-separated string and trims each piece. stringtoarray splits into individual bytes, which are characters only for plain ASCII text — a character such as π or ² is split into broken pieces.
$colors = listtoarray("red, blue, green") // "red", "blue", "green"
$chars = stringtoarray("abc") // "a", "b", "c"
Reading arrays¶
Indexing works as expected, and count, in_array, is_array, array_keys, array_values, array_reverse, array_unique, array_flip and isset are all allowlisted native functions.
$colors = array("red", "green", "blue")
$first = $colors[0] // "red"
$total = count($colors) // 3
$person = array("name" => "Alice", "age" => 25)
$name = $person["name"] // "Alice"
Use isset, not array_key_exists
array_key_exists is not allowlisted. isset($person["email"]) does the
same job for question code.
arrayfindindex($needle, $haystack)¶
The key of the first matching value.
Needle first, haystack second
The reverse of the argument order the old page showed. It returns the key,
or false when the value is absent — so compare with !== false, not >= 0.
$i = arrayfindindex("green", $colors) // 1
arrayfindindices($needle, $haystack) returns all matching keys.
sumarray($array)¶
Adds the elements. Errors if given a non-array.
$total = sumarray(array(3, 5, 8)) // 16
arrayhasduplicates($array)¶
true when any value repeats — useful for asserting that generated distractors are distinct.
$bad = arrayhasduplicates($choices)
Reordering and reshaping¶
sortarray($array, $direction, $maxkey)¶
Returns a sorted copy — it does not sort in place. If the first element is numeric the whole array sorts numerically (non-numeric strings count as 0); otherwise PHP's default comparison is used, which still compares numeric strings as numbers.
$direction |
Effect |
|---|---|
| omitted | ascending |
"rev" |
descending |
"key" |
sort by key rather than value |
"keyfill" |
fill gaps in the keys with "" up to $maxkey, then sort by key |
$sorted = sortarray(array(5, 2, 9)) // 2, 5, 9
$desc = sortarray(array(5, 2, 9), "rev") // 9, 5, 2
splicearray($array, $offset, $length, $replacement)¶
The engine's one editing macro — it covers everything array_push, array_pop, array_shift, array_unshift and array_slice did, and returns a new array.
$nums = array(1, 2, 3)
$appended = splicearray($nums, count($nums), 0, array(4)) // add to the end
$prepended = splicearray($nums, 0, 0, array(0)) // add to the front
$dropfirst = splicearray($nums, 0, 1) // remove the front
$droplast = splicearray($nums, -1, 1) // remove the end
$middle = splicearray($nums, 1, 1) // remove index 1
To read the value you removed, index it before splicing:
$last = $nums[count($nums) - 1]
$nums = splicearray($nums, -1, 1)
subarray($array, $indices…)¶
Picks out selected positions. Each argument is an index, or a "start:end" range string (inclusive).
$picked = subarray($nums, 0, 2) // elements 0 and 2
$range = subarray($nums, "1:2") // elements 1 and 2 (inclusive)
Combining arrays¶
| Macro | Returns |
|---|---|
mergearrays($a1, $a2, …) |
all elements, concatenated; non-array arguments are wrapped |
unionarrays($a1, $a2) |
elements of $a1 plus those of $a2 not already present |
intersectarrays($a1, $a2) |
elements present in both |
diffarrays($a1, $a2) |
elements of $a1 not in $a2 |
$all = mergearrays(array(1, 2), array(3, 4)) // 1, 2, 3, 4
$common = intersectarrays($a, $b)
Calculating across an array¶
| Macro | Purpose |
|---|---|
calconarray($array, $todo) |
apply an expression to every element |
calconarrayif($array, $todo, $ifcond) |
apply it only where a condition holds |
multicalconarray() |
apply across several arrays at once |
keepif($array, $todo) |
keep only elements satisfying a condition |
arraysetvalues($arr, $keys, $values) |
set several keys at once |
jointsort() |
sort several arrays by the first one's order |
jointsort is the sorting counterpart to jointshuffle — use it when values and their labels live in parallel arrays and must stay aligned.
Turning arrays into text¶
joinarray($array, $separator, $ksort) and arraytolist($array, $spaced) are documented on the String Macros page. There is no implode.
$list = joinarray($colors, ", ") // "red, green, blue"
Interpolating an array prints Array
"Colors: $colors" renders the literal word Array. Join it first.
Examples¶
Build randomized multiple-choice options that stay aligned¶
$opts = array("3", "5", "7", "9")
$fb = array("no", "no", "yes", "no")
$opts,$fb = jointshuffle($opts, $fb)
$correct = arrayfindindex("yes", $fb)
Generate a data set and summarize it¶
$data = rands(10, 40, 8)
$data = sortarray($data)
$n = count($data)
$total = sumarray($data)
$mean = $total / $n
Reject a draw that repeats¶
$choices = randsfrom($pool, 4) where (arrayhasduplicates($choices) == false)
diffrandsfrom($pool, 4) does the same thing directly and is preferred — see Randomizers.
See Also¶
- Randomizers —
rands,diffrandsfrom,singleshuffle,jointshuffle - String Macros —
joinarray,arraytolist,listtoarray - Format Macros — displaying numbers
- Control Syntax —
for,foreach,where