Desestructurando con JavaScript y Python.

Alvison Hunter
JavaScript Nicaragua
8 min readJan 28, 2021

Guía básica para desestructurar tanto en JavaScript(ES6) como en Python.

Desestructuración en JavaScript — Photo by Clément Hélardot on Unsplash

A medida que he ido adentrándome en el vasto mundo de la programación, he tenido el honor y más que todo el privilegio de descubrir algunas herramientas y lenguajes, tanto modernos como no tan modernos, que tienen características similares y en algunos casos muchas de estas han sido incorporadas como fuerte bastión de muchos lenguajes de la programación moderna de esta era.

Uno de ellos es JavaScript, un lenguaje al que admiro demasiado, me ha fascinado el hecho de que muchas de las características del ECMA6, las cuales son un conjunto de funcionalidades extraordinarias que enloquecen hasta el más experto y experimentado guerrero del código, tiene una enorme similitud con algunas de otros lenguajes famosos entre ellos Python, lo cual le fortalece en gran manera como herramienta de desarrollo.

Y es que hablando de Python, he venido poco a poco y con el sigilo de un hábil y feroz felino, acercándome al universo de este lenguaje súper versátil, amigable y por ende de fácil aprendizaje el cual posee una elocuencia tan impresionante para expresar algoritmos, por lo que es casi improbable no caer a los pies del mismo sin pensarlo tanto.

Conforme he ido conociendo las características de Python, he logrado notar que una variedad de ellas han sido adoptadas por ECMA6, lo que me ha permitido entenderlas de manera más cómoda y confortable en ambos lados de la moneda, es decir, en ambos lenguajes.

Un ejemplo muy frecuente para ver similitudes son las arrow functions y las lambdas de python, que por su simplicidad hacen la vida las fácil para todos al programar en cualquiera de los dos lenguajes. Veamos un ejemplo usando funciones normales y también su respectivo ejemplo usando funciones anónimas, es decir, funciones sin nombre asignado que sirve para usarse una vez dentro de otra función para generar un resultado que sera usado en la función padre. Es hora de hacer un ejemplo de ambos escenarios, ¿qué les parece, colegas?

Comenzaremos con Python, formulando esta función también con lambda:

# Python function 
def multiply(num):
return num * 2

# Python lambda
multiply = lambda num: num * 2

Ahora veamos el mismo ejemplo pero usando JavaScript puro y con ECMA6:

// JavaScript function
function multiply(n) {
return n * 2;
}

// JavaScript arrow function
const multiply = (num) => num * 2

Lo mismo nos pasa con otras funciones como maps, filters, reduce, generators, iterators, estructuras de clases, operadores ternarios, etc. Por ejemplo, la función map de python funciona de manera similar en JavaScript, o el forEach que se parece también en funcionalidad en ambos lenguajes aunque no se escribe de la misma manera puesto que en Python se vuelve relativamente más cómodo trabajar con objetos iterables simplemente usando un for loop común que hará el papel del forEach iterando con cada elemento de dicho objeto a como lo hacemos en JavaScript a partir de ECMA6.

Veamos un caso interesante para la función map. En ambos lenguajes, map nos va a generar un nuevo objeto, evitando de esta forma tener que cambiar o mutar el objeto iterable original, esto es meramente conveniente para una gama de aspectos en programación y se usa mucho en JavaScript pero no vamos a ahondar en este tema en un solo articulo puesto que es un tema muy extenso, ¿de acuerdo?.

En python, esto lo podemos resolver de diversas formas, veamos 2 de ellas:

numbers = [ 1, 2, 3, 4, 5 ] 
def double(n):
return n* 2
doubles = map(double, numbers)# Otra forma seria usar lambda function para simplificar el proceso
doubles = list(map(lambda n: n* 2, numbers))

Con ECMA6, JavaScript nos permite resolver esto de esta forma:

const numbers  = [1, 2, 3, 4, 5]
const doubles = numbers.map( n => n* 2);
console.log(doubles)

Nota: También existen funciones nativas como pow() que hacen lo mismo y de una manera más rápida pero esta vez usaremos estas funciones solo para ilustrar el escenario de este articulo.

Hay muchísimos ejemplos más pero hoy nos enfocaremos en lo que se llama desempaquetado en la jerga de python o desestructuración en JavaScript, meramente con ECMA6. En ambos casos, esta habilidad debe ser implementada cada vez que codifiques para hacerlo como todo un experto.

De la mano de ECMA6, JavaScript nos permite desestructurar de manera fácil, concisa y precisa: Veamos un ejemplo de esto en el siguiente código:

const [excellent, good, regular, bad] = [“CR7”, “Mbappé”, “Neymar”, “Messi”]
console.log(bad) // Result : ‘Messi’

Si hacemos lo mismo pero con el Python, el código seria algo así:

[excellent, good, regular, bad] = [“CR7”, “Mbappé”, “Neymar”, “Messi”]
print(bad) # Result : ‘Messi’

Con arreglos, si el número de sus elementos es mayor que el número de variables locales pasadas al literal del arreglo de desestructuración, los elementos en exceso no se asignan. Pero si el número de variables locales pasadas al literal del arreglo de desestructuración excede el número de elementos del arreglo, a cada variable local en exceso se le asignará un valor de indefinido, excepto que especifique un valor predeterminado.

Al igual que con la desestructuración de objetos, puede establecer valores predeterminados para las variables locales mediante la desestructuración de arreglos. En el siguiente ejemplo, estableceríamos valores predeterminados para algunas variables en caso de que no se encuentre un elemento correspondiente.

// Valores por defecto
let john = 100;
let clark = 200;
let brad = 50;
// Estos valores nos permitiran actualizarlos
const finalPoints = [200, 255, 100];
// Desestructuramos y asignamos a john y clark
// mientas brad conservara su valor inicial de 50
[john, clark] = finalPoints;
// Result: 'John: 200, Clark: 255, Brad: 50'
console.log(`John: ${john}, Clark: ${clark}, Brad: ${brad}`);

Con Python, para evitar cambiar uno de los valores por defecto que tengamos en el literal de la lista, debemos proceder de la siguiente forma, usando “*_”.

john = 100
clark = 200
brad = 50
finalPoints = [200, 255, 100]# Desestructuramos y asignamos a john y clark
# mientas brad conservara su valor inicial de 50
[john,clark, *_] = finalPoints
# Result: John: 200, Clark: 255, Brad: 50
print(f"John: {john}, Clark: {clark}, Brad: {brad}")

JavaScript permite que desestructuremos solo lo que vayamos a usar, incluso evitando o saltando algunos de los parámetros como en el siguiente ejemplo:

const [excellent, good,, bad] = [“CR7”, “Mbappé”, “Neymar”, “Messi”]
console.log(bad) // Result : ‘Messi’

Con Python para saltarnos o evitar dichos valores, usamos el guión bajo “_”.

[excellent, good, _, bad] = [“CR7”, “Mbappé”, “Neymar”, “Messi”]
print(bad) # Result : ‘Messi’

Para asignar el primer elemento a una variable y el resto de los elementos a otra, hacemos lo siguiente en JavaScript siempre usando ECMA6 como aliado.

const [best, …rest] = [“CR7”, “Mbappé”, “Neymar”, “Messi”]
console.log(rest) // Result : [ ‘Mbappé’, ‘Neymar’, ‘Messi’ ]

En cambio en Python nos auxiliamos del “*” para hacer el desempaquetado:

best, *rest = [“CR7”, “Mbappé”, “Neymar”, “Messi”]
print(rest) # Result : [ ‘Mbappé’, ‘Neymar’, ‘Messi’ ]

Debido a las diversas y potentes funciones de desestructuración que encontramos en el lenguaje de Python, podemos ir mucho más allá de las que nos ofrece el JavaScript usando el ECMA6 y llevar un poco más alto el desempaquetado tradicional al que quizás estamos acostumbrados.

El intercambio de valores subyacentes de variables es la forma más básica de desestructuración y funciona de la siguiente manera:

first, second = second, first

Aunque a un alto nivel puede parecer que ambas declaraciones first = second y second = first solo se ejecutan simultáneamente, en realidad están sucediendo por debajo.

Esencialmente, primero se evalúa el lado derecho, convirtiendo second, first en un tuple. Posteriormente, este tuple se desempaqueta y se asigna al lado izquierdo en el orden de izquierda a derecha.
Consideremos el siguiente fragmento que actualiza los valores de first y second para entender mejor este planteamiento:

first = 1
second = 2
first, second = first + second, first

No le dará un valor 3 para first y second. En cambio, el valor de second después de la asignación sería 1 mientras que first se convierte en 3.

La asignación de desestructuración también nos permite intercambiar más de dos variables:

first, second, third = third, first, second

Otro caso muy cotidiano, que se puede hacer en python es desempaquetar listas con elementos simples y listas como elementos al mismo tiempo.

best, *regulars, bad = [“CR7”, “Mbappé”, “Neymar”, “Messi”]print(best, regulars, bad) 
# Result : CR7 [‘Mbappé’, ‘Neymar’] Messi

Aunque no es tan típico el encontrarnos con casos en donde tenemos que desempaquetar o en todo caso desestructurar objetos iterables en el argumento de alguna función, si el caso lo amerita, como ya es común en frameworks como React, entonces con ECMA6 podemos hacer lo siguiente:

const Developer = {
name:'Alvison Hunter',
city:'Jinotepe',
language:'JavaScript',
}
const getDeveloperInfo = ({name, city, language}) => {
console.log(`Name: ${name} City: ${city} Language: ${language}`)
}
getDeveloperInfo(Developer);

Para hacerlo al estilo de python, o como se conoce en la jerga, a la mera forma pitónica, un argumento de función se desempaqueta usando “**”:

developer = {
“name”: “Alvison Hunter”,
“city”: “Jinotepe”,
“language”: “Python”
}
def get_developer_info(name, city, language):
print(f”Name:{name} City: {city} Language: {language}”)
get_developer_info(**developer)

Es meritorio mencionar que objetos simples construidos en JavaScript se vuelven muy cómodos para trabajarlos con desempaquetamiento o desestructuración, sin embargo, no podemos omitir mencionar que esto se complica a nivel de estructura de dicho objeto y sus diferentes atributos.

const student = { 
first: 'Alvison',
last: 'Hunter',
country: 'Nicaragua'
};
// Desestructuramos el object student de esta forma
const { first, last, country } = student;
console.log(first, last, country); // 'Alvison' 'Hunter' 'Nicaragua'

Para el caso de Python y si este fuera un dictionary, el desempaquetado tuviese un par de opciones mas, quizás, que las presentes en ECMA6, pero al final del día al mismo resultado: Usar desempaquetado o desestructuracion según el caso o el lenguaje, ambas son exactamente lo mismo.

student_dict = {
'first': 'Alvison',
'last': 'Hunter',
'country': 'Nicaragua'
}
def get_student_info():
# Obtener solo las keys del dictionary
# Result: first last country
first, last, country = student_dict
print(first, last, country)
# Obtener solo los values del dictionary
# Result: Alvison Hunter Nicaragua
first, last, country = student_dict.values()
print(first, last, country)
# Obtener keys y values del dictionary como tuples
# ('first','Alvison') ('last','Hunter') ('country', 'Nicaragua')
first, last, country = student_dict.items()
print(first, last, country)

get_student_info()

En conclusion, hemos explorado brevemente la sintaxis de desestructuración de ES6 y en Python asi como varias formas en que podemos utilizarla en nuestro código. La desestructuración o desempaquetado de cualquier objeto iterable debería ser una herramienta necesaria si se deseamos escribir código como un desarrollador experto ya sea en Python, JavaScript o cualquier otro lenguaje. Aparte de esto, el uso de esta tipo de código nos permite reducir el número de líneas de código y puede aumentar la legibilidad del mismo.

Aunque usamos la sintaxis del Rest Parameters de forma básica, vale la pena señalar que aún hay más que puede lograr con ellos. Recomendamos echarle un ojo a la documentación de Spread Syntax y Rest Parameters para obtener más detalles sobre ambos.

Antes de Marcharte, quisiera que leas rapidamente lo siguiente:

👏 Claps si disfrutaste este articulo, así podré motivarme a escribir mas!
🤔 Comenta si tienes algo que decir, es muy importante saber tu opinión.
🙂 Click en seguir Alvison para que estes al tanto de mis nuevos artículos!

Hasta la próxima ocasión, mis estimados lectores!

--

--

Alvison Hunter
JavaScript Nicaragua

JavaScript & Python Developer | Managing Partner @CodeCraftersLabs. Linguist Enthusiast & Music Connoisseur | Husband | Proud Father of 2 brave warriors.🙈🙉🙊