Reputation: 83
Let's say in APL language, I have a 2D array of shape 10x3. I cannot figure it out how to: replace all the occurrence of some specific numbers (e.g. 1, 2, 3, 4) in the entire array with 0, 10, 100, 1000 respectively. So I want to map 1 to 0, 2 to 10, 3 to 100 and 4 to 1000 in the entire array.
Upvotes: 4
Views: 727
Reputation: 7616
I'll be using this example data:
⎕ ← 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
Let's define a helper function to identify occurrences of elements that need to be mapped, namely those that are members of our list of specific numbers:
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
Next, we define a mapping function that looks up the index of each element in the set of specific numbers, and uses those indices to index into the replacements:
Map ← {replacements[specific ⍳ ⍵]}
Map 3 1 4 1
100 0 1000 0
Now we can apply the mapping function at the occurrences:
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
We can define the whole thing as a single replacement function:
Replace ← Map @ Occurrences
Or even go directly for the full definition without the helper functions:
Replace ← {replacements[specific ⍳ ⍵]} @ {⍵ ∊ specific}
The resulting definition will be the same: 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
We can even define a general-purpose replacement operator: 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
This operator definition can be found in APLcart with a query like search and replace elements.
Consider using a mathematical relationship between the specific values and the replacement values, rather than doing a lookup:
( 1 ≠ specific ) × 10 * specific - 1
0 10 100 1000
Now we can write: 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
Upvotes: 5