
Chapter 6: IndexingIndexing is the name given to selecting of elements of arrays by position. This topic includes selecting elements, rearranging selected elements to form new arrays, and amending, or updating, selected elements of arrays.6.1 SelectingThe verb { (leftbrace) is called "From". The expression (x { y) selects elements from y according to positions given by x. For example, recall from Chapter 02 that if L is a list, then the positions of items of L are numbered 0 1 and so on. The expression (0 { L) gives the value of the first item of L and 1 { L gives the second item.
The left argument of { is called the "index". 6.1.1 Common Patterns of Selection.Several items may be selected together:
Items selected from L may be replicated and reordered:
An index value may be negative: a value of _1 selects the last item, _2 selects the nexttolast item and so on. Positive and negative indices may be mixed.
A single element of a table at, say, row 1 column 2 is selected with an index (< 1 ; 2).
We can select from a table all elements in specified rows and columns, to produce a smaller table (called a subarray). To select a subarray consisting of, for example rows 1 and 2 and columns 0 and 1, we use an index (< 1 2; 0 1)
A complete row or rows may be selected from a table. Recall that a table is a list of items, each item being a row. Thus selecting rows from tables is just like selecting items from lists.
To select a complete column or columns, a straightforward way is to select all the rows:
but there are other possibilities: see below. 6.1.2 Take, Drop, Head, Behead, Tail, CurtailNext we look at a group of verbs providing some convenient short forms of indexing. There is a builtin verb {. (left brace dot, called "Take"). The first n items of list L are selected by (n {. L)
If we take n items from L with (n {. L), and n is greater than the length of L, the result is padded to length n, with zeros, spaces or empty boxes as appropriate. For example, suppose we require to make a string of exactly 8 characters from a given string, a description of some kind, which may be longer or shorter than 8. If longer, we shorten. If shorter we pad with spaces.
There is a builtin verb }. (rightbrace dot, called "Drop"). All but the first n items of L are selected by (n }. L).
The last n items of L are selected by (n) {. L. All but the last n are selected by (n) }. L
There are abbreviations of Take and Drop in the special case where n=1. The first item of a list is selected by monadic {. (leftbrace dot, called "Head"). All but the first are selected by }. (rightbrace dot, called "Behead").
The last item of a list is selected by monadic {: (leftbrace colon, called "Tail"). All but the last are selected by }: (rightbrace colon, called "Curtail".
6.2 General Treatment of SelectionIt will help to have some terminology. In general we will have an ndimensional array, but consider a 3dimensional array. A single element is picked out by giving a plane number, a rownumber and a columnnumber. We say that the planes are laid out in order along the first axis, and similarly the rows along the second axis, and the columns along the third.There is no special notation for indexing; rather the left argument of { is a data structure which expresses, or encodes, selections and rearrangements. This data structure can be built in any way convenient. What follows is an explanation of how to build it. 6.2.1 Independent SelectionsThe general expression for indexing is of the form index { array. Here index is an array of scalars. Each scalar in index gives rise to a separate independent selection, and the results are assembled together.
6.2.2 Shape of IndexThe shape of the results depends on the shape of index.
The indices must lie within the range #L to (#L)1:
6.2.3 ScalarsEach scalar in index is either a single number or a box (and of course if one is a box, all are.) If the scalar is a single number it selects an item from array.
If the scalar in index is a box however then it contains a list of selectors which are applied to successive axes. To show where a box is used for this purpose, we can use the name SuAx, say, for the box function. SuAx =: <The following example selects from A the element at row 1, column 0.
6.2.4 Selections on One AxisIn a list of selectors for successive axes, of the form (SuAx p , r, c) say, each of p, r and c is a scalar. This scalar is either a number or a box (and if one is boxed, all are). A number selects one thing on its axis: one plane, row or column as appropriate, as in the last example.However, if the selector is a box it contains a list of selections all applicable to the same axis. To show where a box is used for this purpose we can use the name Sel, say, for the box function. Sel =: <For example, to select from A elements at row 1, columns 0 2:
6.2.5 Excluding ThingsInstead of selecting things on a particular axis, we can exclude things, by supplying a list of thingnumbers enclosed in yet another level of boxing. To show where a box is used for this purpose we can use the name Excl, say, for the box function.Excl =: <For example, to select from A elements at row 0, all columns excluding column 1:
We can select all things on a particular axis by excluding nothing, that is, giving an empty list (0$0) as a list of thingnumbers to exclude. For example, to select from A elements at row 1, all columns:
6.2.6 SimplificationsThe expression (Excl 0$0) denotes a boxed empty list. There is a builtin J abbreviation for this, namely (a:) (lettera colon, called "Ace"), which in this context we can think of as meaning "all".
If in any index of the form (SuAx p,q,..., z), the last selector z is the "all" form, (Sel (Excl 0$0)) or (Sel a:), then it can be omitted.
If in any index of the form (SuAx (Sel p),(Sel q),...), the "all" form is entirely absent, then the index can be abbreviated to (SuAx p;q;...). For example, to select elements at row 1, columns 0 and 2:
Finally, as we have already seen, if selecting only one thing on each axis, a simple unboxed list is sufficient. For example to select the element at row 1, column 2:
6.2.7 Shape of the ResultSuppose that B is a 3dimensional array:B =: 10 + i. 3 3 3and we define p to select planes along the first axis of B, and r to select rows along the second axis, and c to select columns along the third axis: p =: 1 2 r =: 1 2 c =: 0 1We see that, selecting with p;r;c, the shape of the result R is the concatenation of the shapes of p, r and c
B is 3dimensional, and so is R. As we would expect, this concatenationofshapes holds when a selector (r, say) is a list of length one:
and the concatenationofshapes holds when selector r is a scalar:
In this last example, r is a scalar, so the shape of r is an empty list, and so the axis corresponding to r has disappeared, and so the result T is 2dimensional. 6.3 Amending (or Updating) ArraysSometimes we need to compute an array which is the same as an existing array except for new values at a comparatively small number of positions. We may speak of 'updating' or 'amending' an array at selected positions. The J function for amending arrays is } (right brace, called "Amend").6.3.1 Amending with an IndexTo amend an array we need three things:
newvalues index } originalFor example: to amend list L to replace the first item (at index 0) with '*':
} is an adverb, which takes index as its argument to yield the dyadic amending verb (index }). ReplaceFirst =: 0 } '*' ReplaceFirst L *bcdef(index }) is a verb like any other, dyadic and yielding a value in the usual way. Therefore to change an array by amending needs the whole of the result to be reassigned to the old name. Thus amendment often takes place on the pattern: A =: new index } AThe J system ensures that this is an efficient computation with no unnecessary movement of data. To amend a table at row 1 column 2, for example:
To amend multiple elements, a list of new values can be supplied, and they are taken in turn to replace a list of values selected by an index
6.3.2 Amending with a VerbSuppose that Y is a list of numbers, and we wish to amend it so that all numbers exceeding a given value X are replaced by X. (For the sake of this example, we here disregard the builtin J verb (<.) for this function.)The indices at which Y is to be amended must be computed from X and Y. Here is a function f to compute the indices: f =: 4 : '(y > x) # (i. # y)'
The amending is done, in the way we have seen above, by supplying indices of (X f Y):
The "Amend" adverb } allows the expression (X (X f Y) } Y) to be abbreviated as (X f } Y).
Since } is an adverb, it can accept as argument either the indices (X f Y) or the verb f. cap =: f } 10 cap 8 9 10 11 8 9 10 10Note that if verb f is to be supplied as argument to adverb }, then f must be a dyad, although it may ignore X or Y. 6.3.3 Linear IndicesWe have just looked at amending lists with a verb. The purpose of the verb is to find the places at which to amend, that is, to compute from the values in a list the indices at which to amend. With a table rather than a list, the indices would have to be 2 dimensional, and the task of the verb in constructing the indices would be correspondingly more difficult. It would be easier to flatten a table into a linear list, amend it as a list, and rebuild the list into a table again.For example, suppose we have a table: M =: 2 2 $ 13 52 51 14Then, using our indexfinding verb f, the flattening, amending and rebuilding is shown by:
However, there is a better way. First note that our indexfinding verb f takes as argument, not M but (LL =: , M). Thus information about the original shape of M is not available to the indexfinder f. In this example, this does not matter, but in general we may want the indexfinding to depend upon both the shape and the values in M. It would be better if f took the whole of M as argument. In this case f must do its own flattening. Thus we redefine f: f =: 4 : 0 y =. , y (y > x) # (i. # y) )
Now the index finder f takes an array as argument, and delivers indices into the flattened array, socalled "linear indices". The amending process, with this new f, is shown by:
Finally, provided f delivers linear indices, then (}) allows the last expression to be abbreviated as:
6.4 Merging Together the Items of an ArrayWe saw above that } is an adverb. It can be applied to an argument m to generate a verb, (m }) . We saw above the dyadic case of this verb being used to amend an array.Now we look at the monadic case of (m }) . This verb is known as "Amend Items" Let us begin with an example. Suppose T is a table: T =: 3 4 $ 'ABCDEFGHIJKL'Let m be a list of indices. Each item of m is intended to be an index into the corresponding column of T . m =: 1 2 0 2Applying the verb m } to T, we see that the result is produced by indexing down each column separately.
Another way of describing the result is to say that the items of T are combined according to the vector m. The argument of the adverb } can be a boolean array which selects from the first or second of two alternative arrays. For example: A =: 'pot' NB. first alternative B =: 'dig' NB. second alternative 1 0 1 } A ,: B dogThis is the end of Chapter 6. 
The examples in this chapter
were executed using J version 802 beta.
This chapter last updated 14 Jul 2014
Copyright © Roger Stokes 2014.
This material may be freely reproduced,
provided that acknowledgement is made.