I have a Scala app with a list of items with checkboxes so the user select some, and click a button to shift them one position up (left). I decided to write a function to sh
A solution in J:
('abcdefghijklmnopqrstuvwxyz';'ABCDEFGHIJKLMNOPQRSTUVWXYZ') (4 : '(y#~y e. >1{x)([: I. '' ''= ])} }._1&|.&.((1,~y e. >0{x))y,'' ''') 'abcDEfghI'
abDEcfgIh
Let’s break this into named pieces for easier comprehension. The final string “abDEcfgIh
” is the result of applying a function to the string “abcDEfghI
” which is the right argument to the function. The pair of alphabets constitute the left argument to the function (which is the part beginning “(4 :
…”). So, instead of the 2-element vector of boxed strings, we could name each one individually:
'lc uc'=. 'abcdefghijklmnopqrstuvwxyz';'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
Now that we have two variables “lc
” and “uc
” for the lower-case and upper-case alphabets, let’s examine the body of the function in detail. Taking a logically coherent chunk from the right end, since this would be evaluated first, we could name this like so:
rmUCshift=: 4 : 0
}._1&|.&.((1,~y e. >0{x))y,' '
)
This defines “rmUCshift
” as something that requires a right and left argument (the “4 :
” specifies this) with the body beginning on the next line and continuing to the bare closing paren. The “4 : 0
” form, followed by the body, is a variant of the “4 :
‘body’” form shown initially. This verb rmUCshift
can be invoked independently like this:
(lc;'') rmUCshift 'abcDEfghI' NB. Remove upper-case, shift, then insert
ab cfg h NB. spaces where the upper-case would now be.
The invocation is indented three spaces and the output immediately follows the it. The left argument (lc;'')
is a two-element vector with the empty array specified as the second element because it’s not used in this piece of the code – we could have used any value after the semicolon but the two single quotes are easy to type.
The next pieces to name are these (definitions followed by examples):
ixSpaces=: [:I.' '=]
ixSpaces 'ab cfg h'
2 3 7
onlyUC=: 4 : 'y#~y e.>1{x'
('';uc) onlyUC 'abcDEfghI'
DEI
Combining these named pieces together gives us this:
(lc;uc) (4 : '(x onlyUC y)(ixSpaces x rmUCshift y)}x rmUCshift y') 'abcDEfghI'
abDEcfgIh
However, the repetition of “x rmUCshift y
” is unnecessary and can be simplified to give us this:
(lc;uc) (4 : '(x onlyUC y) ((ixSpaces ]) } ]) x rmUCshift y') 'abcDEfghI'
abDEcfgIh