将动词应用于子阵列?

tan*_*orm 4 j

在J中,我可以根据某个谓词更新数组的子集,如下所示:

    y (k}~) |. y {~ k =. I. '123' e.~ y =. '[1.2.3]'
[3.2.1]
Run Code Online (Sandbox Code Playgroud)

我意识到我可以在这里考虑一个连词,但是首先有更优雅的方法吗?这123只是一个例子.具体来说,我想做的是:

  • 获取一个索引数组到一个数组(k)
  • 将这些索引处的数组项提取到一个新数组中
  • 将该数组转换为具有相同类型和形状的新数组
  • 将新数组的值放回插槽中.

此外,重要的是动词作为一个整体在数组上运行,因为我主要想做的是置换和转换子数组.(因此|.在示例中.)

有更简单的方法吗?

Dan*_*ron 5

对此有一个或多或少的标准副词:

   tweak  =: (@:{) (`[) (`]) }
   twist  =: |. tweak
   '123' (I.@:e.~ twist ]) '[1.2.3]'
[3.2.1]
Run Code Online (Sandbox Code Playgroud)

在这里,tweak使用gerundial形式}:

  1. 选择指数x从阵列中y使用{.
  2. 使用绑定连接将转换函数应用于该[sub-]数组@{.也就是说,{选择,并 @:要求动词应用于该选择; twist以|.(反向)形式提供此动词.
  3. 将转换后的[sub] - 阵列返回到相同索引处的原始数组y(由...表示])x(由...表示[).

我会注意到几件事:

  1. J中的子阵列修改相当罕见,因为该语言鼓励整体转换.换句话说:数组的项通常被认为是对等项并且(通常)被平等对待.特别处理某些项目(指数)是不寻常的,需要更加小心,特别是如果选择是临时的(与常规或与某些模式相反).
  2. "就地修改"是一个误导性术语,因为(正如你正确指出的那样),构建了一个新数组,并且这个新数组被修改.真正的就地修改是可能的,但需要不同的方法(涉及名称管理和/或显式代码).
  3. 在您选择的特定示例中存在一些认知不一致:您的查找函数e.本质上是无序的,但您的转换函数|.仅关注订单.这本身没有任何问题,但在重新排序数组的部分(例如,考虑y=.'[1.1.1]')的背景下可能会令人困惑.