Definición
$zipTranspone un arreglo de arreglos de entrada de modo que el primer elemento del arreglo de salida sea un arreglo que contenga, el primer elemento del primer arreglo de entrada, el primer elemento del segundo arreglo de entrada, etc.
Por ejemplo,
$ziptransformaría[ [ 1, 2, 3 ], [ "a", "b", "c" ] ][ [ 1, "a" ], [ 2, "b" ], [ 3, "c" ] ]en.$ziptiene la siguiente sintaxis:{ $zip: { inputs: [ <array expression1>, ... ], useLongestLength: <boolean>, defaults: <array expression> } } OperandoDescripcióninputsUn arreglo de expresiones que se resuelven en arreglos. Los elementos de estos arreglos de entrada se combinan para formar los arreglos del arreglo de salida.
Si alguno de los
inputsarrays se resuelve en un valor denullo hace referencia a un campo faltante,$zipnulldevuelve.Si alguno de los
inputsarrays no se resuelve en un array onullni hace referencia a un campo faltante, devuelve un$ziperror.useLongestLengthUn booleano que especifica si la longitud del arreglo más largo determina el número de arreglos en el arreglo de salida.
El valor por defecto es
false: la longitud más corta del arreglo determina el número de arreglos en el arreglo de salida.defaultsUn array con valores predeterminados para los elementos que se usarán si los arrays de entrada tienen longitudes diferentes. Debe especificar
useLongestLength: truejunto con este campo; de lo contrario,$zipdevolverá un error.Si
useLongestLength: trueperodefaultsestá vacío o no se especifica,$zipusanullcomo valor predeterminado.Si especifica un no
defaultsvacío, debe especificar un valor predeterminado para cada matriz de entrada o, de lo$zipcontrario, devolverá un error.
Comportamiento
Los arreglos de entrada no tienen por qué tener la misma longitud. Por defecto, el arreglo de salida tiene la longitud del arreglo de entrada más corto, pero la useLongestLength opción indica a que genere un arreglo tan largo como el arreglo de entrada más $zip largo.
Ejemplo | Resultados | |||||||
|---|---|---|---|---|---|---|---|---|
| | |||||||
| | |||||||
| | |||||||
| Debido a Cela donne |
Ejemplo
Transposición de matrices
Una colección llamada matrices contiene los siguientes documentos:
db.matrices.insertMany([ { matrix: [[1, 2], [2, 3], [3, 4]] }, { matrix: [[8, 7], [7, 6], [5, 4]] }, ])
Para calcular la transposición de cada matriz 3x2 en esta colección, puedes usar la siguiente operación de agregación:
db.matrices.aggregate([{ $project: { _id: false, transposed: { $zip: { inputs: [ { $arrayElemAt: [ "$matrix", 0 ] }, { $arrayElemAt: [ "$matrix", 1 ] }, { $arrayElemAt: [ "$matrix", 2 ] }, ] } } } }])
Esto devolverá las siguientes matrices 2x3:
{ "transposed" : [ [ 1, 2, 3 ], [ 2, 3, 4 ] ] } { "transposed" : [ [ 8, 7, 5 ], [ 7, 6, 4 ] ] }
Filtrado y preservación de índices
Puedes utilizar $zip con $filter para obtener un subconjunto de elementos en un arreglo, guardando el índice original junto a cada elemento retenido.
Una colección llamada pages contiene el siguiente documento:
db.pages.insertOne( { "category": "unix", "pages": [ { "title": "awk for beginners", reviews: 5 }, { "title": "sed for newbies", reviews: 0 }, { "title": "grep made simple", reviews: 2 }, ] } )
La siguiente pipeline de agregación primero zipeará los elementos del arreglo pages junto con su índice, y luego filtrará solo las páginas con al menos una revisión:
db.pages.aggregate([{ $project: { _id: false, pages: { $filter: { input: { $zip: { inputs: [ "$pages", { $range: [0, { $size: "$pages" }] } ] } }, as: "pageWithIndex", cond: { $let: { vars: { page: { $arrayElemAt: [ "$$pageWithIndex", 0 ] } }, in: { $gte: [ "$$page.reviews", 1 ] } } } } } } }])
Esto devolverá el siguiente documento:
{ "pages" : [ [ { "title" : "awk for beginners", "reviews" : 5 }, 0 ], [ { "title" : "grep made simple", "reviews" : 2 }, 2 ] ] }