Fusionar vectores en APL

Resuelto Jay Mosk asked hace 6 meses • 0 respuestas

Al usar Dyalog APL, me gustaría tomar un vector de máscara donde '-' significa usar el carácter original y cualquier otro carácter debe reemplazar esa posición en el vector de datos. Entonces, en el siguiente ejemplo, la máscara 'a' se usa en el vector 'b' para crear el vector 'c'.

┌──────┬────────┬────┐
│X--Y-Z│--34--91│-+-+│ Mask Vector a
└──────┴────────┴────┘
┌──────┬────────┬────┐
│abcdef│hijklmno│stuv│ Data Vector b
└──────┴────────┴────┘
┌──────┬────────┬────┐
│XbcYeZ│hi34lm91│s+u+│ Resultant Vector c
└──────┴────────┴────┘

Los vectores contienen cadenas de diferentes longitudes. No deseo utilizar ninguna función de expresión regular o búsqueda y reemplazo integrada en APL.

Creé código para realizar esta función, pero parece demasiado complicado ya que se trata de crear matrices, rotar caracteres y extraer datos de filas. Estoy seguro de que existe una forma más sencilla de realizar esta función en APL. Estoy interesado en ver qué se les ocurre a los desarrolladores de APL más experimentados.

Jay Mosk avatar Feb 16 '24 10:02 Jay Mosk
Aceptado

En general, una excelente manera de modificar datos in situ es utilizar el operador At @. Se puede usar de dos maneras diferentes, pero aquí usaremos el patrón substitution_data @ masking_function original_data:

      mask ← 'X--Y-Z' '--34--91' '-+-+'
      data ← 'abcdef' 'hijklmno' 'stuv'
      mask {(⍺~'-')@(⍺≠'-'⍨)⍵}¨ data
┌──────┬────────┬────┐
│XbcYeZ│hi34lm91│s+u+│
└──────┴────────┴────┘

¡Pruébalo en TryAPL!

Usamos un bucle externo {... para procesar cada par de elementos correspondiente de la máscara y los datos. Dentro del dfn {}, está la máscara y los datos .

Los datos de sustitución constan de todos los caracteres excepto los guiones, por lo que eliminamos los guiones con la función Sin~ .

En realidad , el operador aplica la función de enmascaramiento , pero ignora su argumento mediante el operador constante que luego simplemente devuelve el carácter de guión. El guión único se compara con el actual para obtener una máscara que indica qué elementos modificar.@

Adám avatar Feb 16 '2024 07:02 Adám
mask  ← 'X--Y-Z' '--34--91' '-+-+'
data  ← 'abcdef' 'hijklmno' 'stuv'
where ← '-'≠mask
fill ← where/¨mask
(where/¨data) ← fill
data

La operación principal es (where/¨data) ← fill, que es un ejemplo de "asignación selectiva" .

Esta operación se puede definir de manera más sucinta como un operador:

merge ← {d←⍵ ⋄ (w/¨d)←(w←⍺⍺≠⍺)/¨⍺ ⋄ d}

Y llamado en el formulariomask ('-' merge) data

Essie Rivers avatar Feb 16 '2024 04:02 Essie Rivers