j

How to use arbitrary selector in interchange in J lang?


Let's assume we have a vector and matrix like below:

   r =: 100 + 5 5 $ i.25
   r
100 101 102 103 104
105 106 107 108 109
110 111 112 113 114
115 116 117 118 119
120 121 122 123 124

   v =: 100 + 5 $ i.5
   v
100 101 102 103 104

Now I would like to have a way to interchange fragments as specified by selectors. I know how I can exchange items:

   (<0 _1) &C. v
104 101 102 103 100

here I interchanged element at index=0 and index=-1. In case of matrix, the rows (items) are changed:

   (<0 _1) &C. r
120 121 122 123 124
105 106 107 108 109
110 111 112 113 114
115 116 117 118 119
100 101 102 103 104

But what about if I want to specify two arbitrary selections. Example to what I am after:

   sel1 =: (< (<0 1))
   sel1 { v
100 101
   sel2 =: (< (<2 3))
   sel2 { v
102 103

   sel1 sel2 INTERCHANGE v
102 103 100 101 104

And the same for matrix:

   sel1 =: (< (<0 1),(<0 1))
   sel1 { r
100 101
105 106
   sel2 =: (< (<3 4),(<1 2))
   sel2 { r
116 117
121 122
   sel1 sel2 INTERCHANGE r
116 117 102 103 104
121 122 107 108 109
110 111 112 113 114
115 100 101 118 119
120 105 106 123 124

So my question would be how to define elegantly interchange that uses two selections?


Solution

  • I think that I would first create the two selections and then use Amend to swap them. May not be the most elegant or generalizable, but if you know the selections that you want to change and they are the same shape, it does work.

       r
    100 101 102 103 104
    105 106 107 108 109
    110 111 112 113 114
    115 116 117 118 119
    120 121 122 123 124
         [rep=:((<3 4;1 2),(<0 1;0 1)) {  r  NB. rep is the selected replacement values
    116 117
    121 122
    
    100 101
    105 106
       ((<0 1;0 1),(<3 4;1 2)){ r  NB. values that will be replaced (just a check that they are the same shape)
    100 101
    105 106
    
    116 117
    121 122
      rep ((<0 1;0 1),(<3 4;1 2))} r  NB. Select verb ({) changed to Amend adverb (})
    116 117 102 103 104
    121 122 107 108 109
    110 111 112 113 114
    115 100 101 118 119
    120 105 106 123 124