Me gustaría fusionar matrices en YAML y cargarlas a través de ruby -
some_stuff: &some_stuff
- a
- b
- c
combined_stuff:
<<: *some_stuff
- d
- e
- f
Me gustaría tener la matriz combinada como [a,b,c,d,e,f]
Recibo el error: no encontré la clave esperada al analizar una asignación de bloque
¿Cómo fusiono matrices en YAML?
list
data-structures
yaml
lfender6445
fuente
fuente
Respuestas:
Si el objetivo es ejecutar una secuencia de comandos de shell, puede lograrlo de la siguiente manera:
Esto es equivalente a:
He estado usando esto en mi
gitlab-ci.yml
(para responder @ rink.attendant.6 comentario sobre la pregunta).Ejemplo de trabajo que usamos para admitir
requirements.txt
tener repositorios privados de gitlab:donde
requirements_test.txt
contiene, por ejemplo-e git+ssh://[email protected]/example/[email protected]#egg=example
fuente
Actualización: 2019-07-01 14:06:12
Contexto
Esta publicación asume el siguiente contexto:
Problema
lfender6445 desea fusionar dos o más listas dentro de un archivo YAML, y que esas listas fusionadas aparezcan como una lista singular cuando se analizan.
Solución (solución alternativa)
Esto se puede obtener simplemente asignando anclajes YAML a las asignaciones, donde las listas deseadas aparecen como elementos secundarios de las asignaciones. Sin embargo, hay algunas salvedades (consulte "Errores" más adelante).
En el siguiente ejemplo, tenemos tres asignaciones (
list_one, list_two, list_three
) y tres anclajes y alias que se refieren a estas asignaciones cuando corresponda.Cuando se carga el archivo YAML en el programa, obtenemos la lista que queremos, pero es posible que requiera una pequeña modificación después de la carga (vea las trampas a continuación).
Ejemplo
Archivo YAML original
Resultado después de YAML.safe_load
Trampas
Conclusión
Este enfoque permite la creación de listas fusionadas mediante el uso de la función de alias y ancla de YAML.
Aunque el resultado de salida es una lista anidada de listas, esto se puede transformar fácilmente usando el
flatten
método.Ver también
Enfoque alternativo actualizado por @Anthon
Ejemplos del
flatten
métodoflatten
;; Fusionar / aplanar una matriz de matricesflatten
;; http://ruby-doc.org/core-2.2.2/Array.html#method-i-flattenflatten
;; https://softwareengineering.stackexchange.com/a/254676/23884fuente
Esto no va a funcionar:
la combinación solo es compatible con las especificaciones YAML para asignaciones y no para secuencias
está mezclando completamente las cosas al tener una clave de combinación
<<
seguida del separador de clave / valor:
y un valor que es una referencia y luego continúa con una lista en el mismo nivel de sangríaEsto no es correcto YAML:
Por lo tanto, su sintaxis de ejemplo ni siquiera tendría sentido como propuesta de extensión YAML.
Si desea hacer algo como fusionar varias matrices, es posible que desee considerar una sintaxis como:
donde
s1
,s2
,s3
son anclas en secuencias (no mostrados) que desea combinar en una nueva secuencia y luego tener eld
,e
yf
adjuntas a eso. Pero YAML primero está resolviendo este tipo de estructuras en profundidad, por lo que no hay un contexto real disponible durante el procesamiento de la clave de combinación. No hay una matriz / lista disponible a la que pueda adjuntar el valor procesado (la secuencia anclada).Puede adoptar el enfoque propuesto por @dreftymac, pero esto tiene la gran desventaja de que de alguna manera necesita saber qué secuencias anidadas aplanar (es decir, conociendo la "ruta" desde la raíz de la estructura de datos cargada hasta la secuencia principal), o que recorra de forma recursiva la estructura de datos cargada en busca de matrices / listas anidadas y las aplana todas indiscriminadamente.
En mi opinión, una mejor solución sería usar etiquetas para cargar estructuras de datos que hagan el acoplado por usted. Esto permite indicar claramente qué se debe aplanar y qué no, y le brinda un control total sobre si este aplanamiento se realiza durante la carga o durante el acceso. Cuál elegir es una cuestión de facilidad de implementación y eficiencia en tiempo y espacio de almacenamiento. Esta es la misma disyuntiva que hay que hacer para implementar la combinación de la tecla función y no hay una solución única que siempre es la mejor.
Por ejemplo, mi
ruamel.yaml
biblioteca usa los dictados combinados de fuerza bruta durante la carga cuando usa su cargador seguro, lo que da como resultado diccionarios combinados que son dictados normales de Python. Esta fusión debe realizarse por adelantado y duplica los datos (espacio ineficaz) pero es rápida en la búsqueda de valor. Al usar el cargador de viaje de ida y vuelta, desea poder volcar las fusiones sin fusionar, por lo que deben mantenerse separadas. El dict como estructura de datos cargada como resultado de la carga de ida y vuelta, es eficiente en el espacio pero más lento en el acceso, ya que necesita intentar buscar una clave que no se encuentra en el dict mismo en las fusiones (y esto no se almacena en caché, por lo que debe hacerse cada vez). Por supuesto, estas consideraciones no son muy importantes para archivos de configuración relativamente pequeños.Lo siguiente implementa un esquema similar a la fusión para listas en Python usando objetos con etiqueta
flatten
que sobre la marcha recurre a elementos que son listas y etiquetadostoflatten
. Usando estas dos etiquetas puede tener un archivo YAML:(el uso de secuencias de estilo de flujo frente a bloque es completamente arbitrario y no influye en el resultado cargado).
Al iterar sobre los elementos que son el valor de la clave,
m1
esto "recurre" a las secuencias etiquetadas contoflatten
, pero muestra otras listas (con alias o no) como un solo elemento.Una forma posible con el código Python de lograrlo es:
que salidas:
Como puede ver, puede ver, en la secuencia que necesita acoplarse, puede usar un alias para una secuencia etiquetada o puede usar una secuencia etiquetada. YAML no te permite hacer:
, es decir, etiquetar una secuencia anclada, ya que esto esencialmente la convertiría en una estructura de datos diferente.
Usar etiquetas explícitas es IMO mejor que tener algo de magia como con las claves de combinación YAML
<<
. Si nada más, ahora tiene que pasar por aros si tiene un archivo YAML con una asignación que tiene una clave<<
que no desea que actúe como una clave de combinación, por ejemplo, cuando hace una asignación de operadores C a sus descripciones. en inglés (o en algún otro idioma natural).fuente
Si solo necesita combinar un elemento en una lista, puede hacerlo
cuyos rendimientos
fuente
Puede fusionar asignaciones y luego convertir sus claves en una lista, bajo estas condiciones:
fuente