APL:数组的元素替换和乘法

问题描述

用APL语言说,我有一个10x3形状的2D数组。我不知道如何: 用整个数组分别替换为0、10、100、1000的所有特定数字(例如1、2、3、4)。所以我想在整个数组中映射1到0、2到10、3到100和4到1000。

解决方法

我将使用以下示例数据:

      ⎕ ← array ← ? 10 3 ⍴ 10
 5  7  8
10  2 10
 9  8 10
 3  5  4
 6  6  4
 2  9  7
 4  5 10
 1  9  4
 1 10  1
10  5  3
      specific ← 1 2 3 4
      replacements ← 0 10 100 1000

让我们定义一个辅助函数,以识别需要映射的元素的出现,即那些属于我们特定数字列表的成员

      Occurrences ← {⍵ ∊ specific}
      Occurrences array
0 0 0
0 1 0
0 0 0
1 0 1
0 0 1
1 0 0
1 0 0
1 0 1
1 0 1
0 0 1

接下来,我们定义一个映射函数,该函数查找一组特定数字中每个元素的索引,并使用这些索引索引替换项:

      Map ← {replacements[specific ⍳ ⍵]}
      Map 3 1 4 1
100 0 1000 0

现在,我们可以在出现的位置应用映射功能

      Map @ Occurrences array
   5  7    8
  10 10   10
   9  8   10
 100  5 1000
   6  6 1000
  10  9    7
1000  5   10
   0  9 1000
   0 10    0
  10  5  100

我们可以将整个事物定义为单个替换函数:

      Replace ← Map @ Occurrences

或者甚至直接使用完整的定义,而无需帮助功能:

      Replace ← {replacements[specific ⍳ ⍵]} @ {⍵ ∊ specific}

得到的定义将是相同的:Try it online!

      Replace array
   5  7    8
  10 10   10
   9  8   10
 100  5 1000
   6  6 1000
  10  9    7
1000  5   10
   0  9 1000
   0 10    0
  10  5  100

我们甚至可以定义通用替换运算符:Try it online!

      _Replace_ ← {⍺⍺ ( ⍵⍵ ⌷⍨∘⊂ ⍳ ) @ ( ∊∘⍺⍺ ) ⍵}
      (specific _Replace_ replacements) array
   5  7    8
  10 10   10
   9  8   10
 100  5 1000
   6  6 1000
  10  9    7
1000  5   10
   0  9 1000
   0 10    0
  10  5  100

可以在APLcart中用a query like search and replace elements找到该运算符定义。


考虑在特定值和替换值之间使用数学关系,而不是进行查找:

      ( 1 ≠ specific ) × 10 * specific - 1
0 10 100 1000

现在我们可以写:Try it online!

      {( 1 ≠ ⍵ ) × 10 * ⍵ - 1} @ {⍵ ∊ specific} array
   5  7    8
  10 10   10
   9  8   10
 100  5 1000
   6  6 1000
  10  9    7
1000  5   10
   0  9 1000
   0 10    0
  10  5  100