# Phrases/DataStructures

From J Wiki

< Phrases

### A Method for Accessing Multilevel Structures by Name

The `fstr` adverb can save some typing if you have multilevel structures and use its naming convention for referring to the components. The convention is that the structure items have names of the form `strname_fieldname` where `strname`, the structure name, is the same for all items. If a structure item is a box containing another structure, the `fieldname` for the item should be the same as the `strname` for the enclosed structure. Without the `fstr` adverb, a sample reference to a nested structure might be:

HISTORY_STATUS_STS { > HISTORY_STATUS { > ORDER_HISTORY { > IUNIT_ORDER { y. }}} but with `fstr` this is shortened to {{{

'IUNIT?^:ORDER!^:HISTORY!^STATUS!^STS' fstr y.

NB. Adverb. m. describes an item to be fetched, as NB. spec[!spec]...[!] NB. where spec is NB. [prefix?]expr NB. where prefix is a character string which (boxed) becomes NB. the prefix, or a number, which tells how many trailing NB. items of the incoming prefix to keep. Default is _, meaning NB. keep the whole prefix NB. and expr is an expression which is evaluated to give a selector. NB. This selector (after being boxed) is applied to the input at that NB. level. All '^' and '^:' appearing in the input are replaced by the current NB. path, razed with '_' after each item. If '^:' appears in the NB. input, the current path is cleared after all the replacements. NB. After that, the path is extended by adding the token following the NB. first '^' or '^:', if there is one. NB. The specs are processed left-to-right. When '!' is encountered, NB. the result of the selection is unboxed (and subsequent selections are NB. applied to each atom after it is unboxed) NB. Ex: 'IUNIT?^:ORDER!^:HISTORY!^STATUS!^STS' fstr NB. x. is one unboxed spec string, y. is incoming path (a list of boxed strings), result is path to use here inputpath =. ( ({.~ i.&'?') ux_vy ((<@[) ` (0&". ux_vy trailing) @. (*./@(e.&'0123456789')@[)) ) ^:('?'&e.@[) NB. x. is one unboxed spec string, y. is path to use here, result is path to use at next level outputpath =. ( ;: ux_vy ( -.@((<'^:')&e.) ux_vy # , ({~ >:@(i.&1)@(e.&((,'^');'^:')))@[ ) ) ^: ('^'&e.@[) NB. x. is one boxed spec string, y. is (accumulated path[;garbage]) NB. Result is (path for next level;path to use at this level) accumpath =. ([ (outputpath ,&< ]) inputpath)&> {. NB. y. is spec string (boxed in pieces), result is prefix string to use at each level buildpaths =. ;@:(,&'_'&.>)&.>@:({:"1)@:((accumpath/\.)&.(,&(<0$a:)))&.|. NB. x. is boxed pieces of the spec string, y. is list of boxed paths NB. result is x. with substitutions made for ^ and ^: substpath =. (<;._2@(,&'^')@(#~ -.@(|.!.0)@('^:'&E.))@((}.~ >:@(i.&'?'))^:('?'&e.))@> ux_vy (<@;@}:@,@,.))"0 NB. y. is the spec string, result is selection info, with substitutions NB. performed (and '!' indicating unboxing) brktospecs =. (substpath buildpaths) @ (<;.1~ (+. |.!.1)@('!'&=)) NB. y. is the spec string. Result is NB. a list of ARs, one for each spec and one for each ! arofspecs =. ('&' arconj&(arverb '{')@arnoun@(".&.>))`((arverb '>')"_) @. ((<,'!')&-:) "0 @: brktospecs NB. Convert each component to an AR, and then roll up the ARs. We go from NB. the right-hand end, but we add each element to the left of the accumulated NB. AR, so this has the effect of reversing the order and left-grouping the NB. result fstrar =: ('@' arconj)~/ @: arofspecs f. fstr =: 1 : '(fstrar m.)`:6'