Fit conjunction (!.) applied to expand
Is it possible to specify a default value for expand
with !.
, the fit conjunction? Normally, it is possible to specify a default fill value for #
, but what about #^:_1
?
For example, something like
empty =. <0 0$''
r =. 0 1 0 1 expand!.empty 'foo';'bar' NB. Actually a domain error
++---+---++
||foo|bar||
++---+---++
$ each r
+---+-+-+---+
|0 0|3|3|0 0|
+---+-+-+---+
All I've 开发者_开发百科tried throws domain errors:
expand!.empty
#^:_1!.empty
#!.empty^:_1
(#!.empty)^:_1
Yes:
0 1 0 1 expand f.!.empty 'foo';'bar' NB. with f. works fine
++---++---+ ||foo||bar| ++---++---+
The trick is to use f.
or #^:_1
anonymously, so that !.
sees #^:_1
as its left argument, instead of expand
. Fit isn't as smart as it could be.
I am not aware of any way to use the fit conjunction to alter the fill for expand
(#^:_1
)
The technique I do know how to use is to write an equivalent to expand
for which we specify the fill element.
The following code allows custom expansion such as you've described. It has been written to work with version 5, since you indicated you rely on that, but I have only tested it under version 6. As usual, this is likely susceptible to further refinement.
xpand=: 1 :'((retention j. expansion)@:[ #!.u prep@:])'
prep=: ,~ {.
retention=: 0:, +/ # 1:
expansion=: [:forwarddifference [:tallyzeros [:partition [:<\ pad
forwarddifference=: 2&(-~/\)
tallyzeros=: +/ @: -. &>
partition=: #~ (1: = {:)&>
pad=: 1&([,~ ,)
NB. example of use
empty =. <0 0$''
]r=. 0 1 1 0 empty xpand 'foo';'bar'
┌┬───┬───┬┐
││foo│bar││
└┴───┴───┴┘
$ each r
┌───┬─┬─┬───┐
│0 0│3│3│0 0│
└───┴─┴─┴───┘
Since posting the original answer I obtained a more concise alternative:
xpand =: 1 :' index @:[ { u,~] '
index =: retain + insert
retain=: I.@:] }~ [:i.+/
insert=: +/ * -.
Note that the u,~]
portion is not compatible with version 5. Use ],u"_
instead for compatibility.
Another approach might be:
inv=: ^:_1
1 0 1 0 1 ((#inv #\) { 'z'&,@]) 'abc'
azbzc
Replace the nouns with whatever nouns you want to be working with...
Thus:
fillExpand=:1 :'(#inv #\) { m&,@]'
empty=:<i.0 0
0 1 0 1 empty fillExpand ;:'foo bar'
++---++---+
||foo||bar|
++---++---+
$&.>0 1 0 1 empty fillExpand ;:'foo bar'
+---+-+---+-+
|0 0|3|0 0|3|
+---+-+---+-+
That said, note that #\ is inefficient under version 5. In version 5, I would replace #\ with 1: + i.@#
That said, note that Dan Bron's suggestion #!.empty^:_1 works fine for me, and I thought should work fine in version 5.
精彩评论