Philip wrote:
>  v =. 2 2 $ 2; 1 3 5 ; 3 ; 1 4 
>  I'd like to replace the elements formed in row  0  of v   [2]
>  by  10 and also those formed by row  1  of  v  by  20 . 
>  Is there a way to do this? 

The problem is the parenthetical clause from this sentence in the Dictionary:

   http://www.jsoftware.com/help/dictionary/d530n.htm

   If  m  is not a gerund,  x m} y  is formed by 
   replacing by  x  those parts of  y  selected by 
   m&{ (an error is signalled if such selection 
   requires fill).

That is, the indices of amendment must select a rectangular array.  In   _2 2 $ 
 2;1 3 5  ;  3;1 4  the first row selects three
elements, but the second row only selects two.  Therefore, given:

           Y        =:  4 6 $_
           
           I        =:  _2 <\ 2;1 3 5  ;  3;1 4  NB.  {  is rank 0
           
then:

           I { Y
        _ _ _
        _ _ 0
        
           10 20 I} Y   NB.  In this case  x  is irrelevant.
        |domain error
        |   10 20     I}Y
        |[-6] c:\app\dev\lang\j\current\temp\89.ijs
           
OTOH, if the selection were rectangular:

           I        =:  _2 <\ 2;1 3 5  ;  3;1 2 4  NB.  Added an element
           
           I { Y
        _ _ _
        _ _ _
           
           (10 10 10 ,: 20 20 20) I} Y  NB.  Here  x  must have the same shape 
as  I{Y
        _  _  _  _  _  _
        _  _  _  _  _  _
        _ 10  _ 10  _ 10
        _ 20 20  _ 20  _
           
Note that  10 20 I} Y  won't work [1].

Anyway, given your data, you have a number of options to get the result you 
want.  However, none I can think of are pretty.
Here's the first one that occurred to me:


           I        =:  _2 ]\ 2;1 3 5  ;  3;1 4  NB. No need to box rows for 
this
           
           X        =:  10 20 ; < I
           
           amend0   =:  dyad define
                'd i'=.x
                
                d =. ; d #&.>~  #&> {:"1 i
                i =. ; (<@:{"1) I  NB.  Cartesian is the key.
                
                d i} y
        )
           
           X amend0 Y
        _  _ _  _  _  _
        _  _ _  _  _  _
        _ 10 _ 10  _ 10
        _ 20 _  _ 20  _

Or tacitly:
           
           amend0t  =:  
;@:((#&.>~#&>@:({:"1))&>/)@:[`(;@:(<@:{"1)@:>@:{:@:[)`]} 
           
           X (amend0t -: amend0) Y
        1
                   
Another method uses Jose's sequential application adverb:  

           seq      =:  (((&.>)/)(@:(|.@:[ , <@:])))(>@:)  NB.  Quintana

           amend1t  =:  >@:{.@:[`(}.@:[)`] } seq
           
           (10 20 (<@:;<)"_1 I) amend1t Y
        _  _ _  _  _  _
        _  _ _  _  _  _
        _ 10 _ 10  _ 10
        _ 20 _  _ 20  _
           
           
Another makes the selection rectangular, then amends twice:

           amend2   =:  dyad define
                'd i'   =.  x
                'i0 i1' =.  i <@:,;.1~ '';1
             zi     =.  i0 (<@:,<)"_1 pad =.  >i1  NB.  Pad short rows
             z      =.  (d #"0~ {:$pad) zi} y
             zi     =.  < 0 ;~ ; i0 #~ ,pad >&:(0&e.)S:0"_1 i1
             z      =.  (zi{y) zi} z
        )
           
           X amend2 Y
        _  _ _  _  _  _
        _  _ _  _  _  _
        _ 10 _ 10  _ 10
        _ 20 _  _ 20  _

Or tacitly:

           NB.  Following def is all one line

           amend2t =: (;~ ((; <@:;&:, 0:)@:#~ [: (~: >./) #&>)/@:|:@:>@:{:)~ 
{&>/@:[`(>@:{.@:[)`] }  (#"0~ [: >./
#&>@:({:"1))&>/@:[`((<@:(,<)"_1 >)/@:|:@:]&:>/@:[)`]}

           X (amend2t -: amend2) Y
        1

I haven't compared these methods in terms of efficiency.  I'm betting the 
explicit code is more efficient.  With a little more
work you could rewrite them to leverage the special code for amend:

   http://www.jsoftware.com/help/release/iamend.htm

And I'm sure there are other formulations I haven't even considered.  If anyone 
comes up with a pretty (short) one, please post
it.

-Dan

[1]   I guess in this sense prefix agreement doesn't apply to  }  .  I will try 
to work up a general model for it and submit it as
a feature request; the DoJ does not prohibit the extension.

[2]  I would not use  v  as a variable name.  In fact, I would not assign to 
any of  x y u v m n  except locally where they're
previously defined and the assignment retains their nameclass.

----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to