{
    "componentChunkName": "component---node-modules-gatsby-theme-try-ghost-src-templates-post-js",
    "path": "/go-go-power-ra-ah-que-no-go-parte-5-maps/",
    "result": {"data":{"ghostPost":{"id":"Ghost__Post__5a338158333e0f134c248f16","title":"Go Go Power Ra....ah que no: Go Parte 5 - Maps","slug":"go-go-power-ra-ah-que-no-go-parte-5-maps","featured":false,"feature_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Untitled-2.png","excerpt":"Espero que este post sea bastante rápido jejejejej.\nEn este caso hablaremos de los Maps o lo que en otros lenguajes conoceríamos\ncomo diccionario. En general siguen las mismas teorías que los arrays o los \nslices en cuanto a creación y a lo referente al rendimiento, los mapas crecen\ndinámicamente pero podemos indicarles el tamaño lo que optimizaría un poco su\nrendimiento.\n\nCreación\nEmpecemos con la creación. Como ya hemos visto en Go tenemos siempre varias\nformas de crear los elementos:\n\n * Form","custom_excerpt":null,"visibility":"public","created_at_pretty":"19 Jul 2017","published_at_pretty":"23 Jul 2017","updated_at_pretty":"11 Oct 2017","created_at":"2017-07-19T21:45:34.000+02:00","published_at":"2017-07-23T10:57:00.000+02:00","updated_at":"2017-10-11T13:46:33.000+02:00","meta_title":null,"meta_description":null,"og_description":null,"og_image":null,"og_title":null,"twitter_description":null,"twitter_image":null,"twitter_title":null,"authors":[{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":null}],"primary_author":{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":{"base":"Perfil.jpg","publicURL":"/static/b0de6281fb28a266510b3b09b9243e5a/Perfil.jpg","imageMeta":{"width":307,"height":307},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAUDBAb/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAGzw6zC6zHn+cLYP//EAB0QAAICAQUAAAAAAAAAAAAAAAEDAAIEEyEiIzL/2gAIAQEAAQUCifca8KgcKWVfUpkHsG5pxX//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/AR//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/AR//xAAdEAACAgEFAAAAAAAAAAAAAAAAARARcQISIUFR/9oACAEBAAY/AhU88xkb7N06a8P/xAAcEAEAAwEAAwEAAAAAAAAAAAABABEhMUFRYXH/2gAIAQEAAT8hR2pq40aqb+xIAeXibhW9JXr8joF4TBcSNe0//9oADAMBAAIAAwAAABDzDwD/xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/EB//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/EB//xAAcEAEAAgIDAQAAAAAAAAAAAAABABEhUTFhcfD/2gAIAQEAAT8QyItrELaTlatLwU63MvEW6vUNdy4LZQDn7iVApV9VLtANdWwKkuYq4Er1VZ//2Q==","aspectRatio":1,"src":"/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg","srcSet":"/static/b0de6281fb28a266510b3b09b9243e5a/f340b/Perfil.jpg 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/22d64/Perfil.jpg 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/aa249/Perfil.jpg 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/0dc33/Perfil.jpg 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/60667/Perfil.jpg 307w","srcWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp","srcSetWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/59cda/Perfil.webp 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/7da75/Perfil.webp 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f282e/Perfil.webp 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/a7b21/Perfil.webp 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f59af/Perfil.webp 307w","sizes":"(max-width: 110px) 100vw, 110px"}}}},"primary_tag":{"slug":"go","url":"https://jlgarcia.fulldev.ninja/tag/go/","name":"Go","visibility":"public","feature_image":null,"description":null,"meta_title":"Golang Ninjas","meta_description":"Aprenderemos a usar el nuevo lenguaje de Google para backend desde lo más básico a temas avanzados como concurrencia o api rest.","featureImageSharp":null},"tags":[{"slug":"go","url":"https://jlgarcia.fulldev.ninja/tag/go/","name":"Go","visibility":"public","feature_image":null,"description":null,"meta_title":"Golang Ninjas","meta_description":"Aprenderemos a usar el nuevo lenguaje de Google para backend desde lo más básico a temas avanzados como concurrencia o api rest.","featureImageSharp":null},{"slug":"golang","url":"https://jlgarcia.fulldev.ninja/tag/golang/","name":"Golang","visibility":"public","feature_image":null,"description":null,"meta_title":"Golang Ninjas","meta_description":"Aprenderemos a usar el nuevo lenguaje de Google para backend desde lo más básico a temas avanzados como concurrencia o api rest.","featureImageSharp":null}],"plaintext":"Espero que este post sea bastante rápido jejejejej.\nEn este caso hablaremos de los Maps o lo que en otros lenguajes conoceríamos\ncomo diccionario. En general siguen las mismas teorías que los arrays o los \nslices en cuanto a creación y a lo referente al rendimiento, los mapas crecen\ndinámicamente pero podemos indicarles el tamaño lo que optimizaría un poco su\nrendimiento.\n\nCreación\nEmpecemos con la creación. Como ya hemos visto en Go tenemos siempre varias\nformas de crear los elementos:\n\n * Forma básica\n\n//var nombreVariable map[tipoClave]tipoValor\nvar rangerRojo map[string]int\n\n\n * Declaración corta:\n\n//Inicializando sin valores\nrangerRojo := map[string]int{}\n\n//Inicializando con valores. Obligatoria la coma ultima\nrangerVerde := map[string]int{\n \"Fuerza\": 10000,\n \"Resistencia\": 5000,\n}\n\n\n * Usando make\n\nrangerVerde := make(map[string]int)\n//Al igual que en los arrays podemos indicar el tamaño para optimizar rendimiento.\nrangerNegro := make(map[string]int, 2)  \n\n\nUsando Map\nYa hemos visto un poco como es la creación de Maps en golang, no es muy\ncomplicado no?, veamos ahora algunos detalles de su uso.\n\nCuando asignamos el valor, realmente este devuelve 2, el contenido que queremos\nsacar y si existe o no. Veamoslo con un ejemplo:\n\nrangerRojo := map[string]int{\n  \"Fuerza\": 10000,\n}\n\nrangerVerde := make(map[string]int)\n\npower, exist := rangerRojo[\"Fuerza\"]\nfmt.Println(\"Valor: \", power, \"Existe: \", exist)\n\npower2, exist2 := rangerVerde[\"Fuerza\"]\nfmt.Println(\"Valor: \", power2, \"Existe: \", exist2)\n\n\nHe usado dos formas de crear maps y el resultado de esto seria:\n\n\nComo veis nos inicializa el valor como suele hacer Go y nos indica que no existe\nrealmente.\n\nBorrando contenido de un Map\nEn este caso Go se vuelve muy útil tiene una función propia para poder eliminar\nel elemento que queramos:\n\ndelete(rangerRojo,\"Fuerza\")\n\n\nProbémoslo en un ejemplo más completo:\n\nrangerRojo := map[string]int{\n\t\"Fuerza\":      10000,\n\t\"Resistencia\": 500,\n}\nfmt.Println(rangerRojo)\n\ndelete(rangerRojo, \"Fuerza\")\n\nfmt.Println(rangerRojo)\n\n\nY como vemos elimina el contenido sin problemas:\n\n\nRecorrer un MAP\nPara recorrer un MAP usamos la misma teoría que para los arrays o slices: RANGE \nvamos directos al ejemplo ya que es bastante simple:\n\nrangerRojo := map[string]interface{}{\n  \"Fuerza\":       10000,\n  \"Resistencia\":  500,\n  \"Inteligencia\": \"200\",\n  \"Arma\":         \"Espada\",\n}\n\nfor key, value := range rangerRojo {\n  fmt.Println(\"Clave: \", key, \" Valor: \", value)\n}\n\n\nTenemos un map que tiene como claves varios strings representando las\ncaracterísticas de nuestro ranger y como valor he introducido algo que no\nhabiamos visto todavia INTERFACE{}, bueno como resumen haceros a la idea de que\nes un tipo especial que funciona como un genérico, es decir, que representa\ncualquier valor(por eso podemos tener valores tipo INT y tipo STRING) y al\nrecorrerlo tenemos esto:\n\nOJO a tener en cuenta, no tiene porque hacerlo en orden sobretodo si\nintroducimos algo a posteriori, mirar un ejemplo:\n\nrangerRojo := map[string]interface{}{\n  \"Fuerza\":       10000,\n  \"Resistencia\":  500,\n  \"Inteligencia\": 150,\n  \"Arma\":         \"Espada\",\n}\n\nrangerRojo[\"Maná\"] = 150\n\nfor key, value := range rangerRojo {\n  fmt.Println(\"Clave: \", key, \" Valor: \", value)\n}\n\n\nHe añadido otra propiedad a nuestro ranger y el resultado es:\n\n\nSi lo ejecuto de nuevo:\n\n\n\nPor último y como he adelantado en el ejemplo anterior:\n\nAñadir elementos a nuestro MAP\nBueno como ya hemos visto esto es muy sencillo:\n\nrangerRojo[\"Maná\"] = 150\n\nfmt.Println(rangerRojo)\n\n\nY nos muestra\n\nPor el momento hemos terminado con los mapas, profundizaremos en el trabajo con\nellos más adelante.\nSin mucho más nos vemos en la siguiente superNinjas :)","html":"<!--kg-card-begin: markdown--><p>Espero que este post sea bastante rápido jejejejej.<br>\nEn este caso hablaremos de los <strong>Maps</strong> o lo que en otros lenguajes conoceríamos como diccionario. En general siguen las mismas teorías que los <strong>arrays</strong> o los <strong>slices</strong> en cuanto a creación y a lo referente al rendimiento, los mapas crecen dinámicamente pero podemos indicarles el tamaño lo que optimizaría un poco su rendimiento.</p>\n<h1 id=\"creacin\">Creación</h1>\n<p>Empecemos con la creación. Como ya hemos visto en Go tenemos siempre varias formas de crear los elementos:</p>\n<ul>\n<li>Forma básica</li>\n</ul>\n<pre><code>//var nombreVariable map[tipoClave]tipoValor\nvar rangerRojo map[string]int\n</code></pre>\n<ul>\n<li>Declaración corta:</li>\n</ul>\n<pre><code>//Inicializando sin valores\nrangerRojo := map[string]int{}\n\n//Inicializando con valores. Obligatoria la coma ultima\nrangerVerde := map[string]int{\n &quot;Fuerza&quot;: 10000,\n &quot;Resistencia&quot;: 5000,\n}\n</code></pre>\n<ul>\n<li>Usando <strong>make</strong></li>\n</ul>\n<pre><code>rangerVerde := make(map[string]int)\n//Al igual que en los arrays podemos indicar el tamaño para optimizar rendimiento.\nrangerNegro := make(map[string]int, 2)  \n</code></pre>\n<h1 id=\"usandomap\">Usando Map</h1>\n<p>Ya hemos visto un poco como es la creación de <strong>Maps</strong> en golang, no es muy complicado no?, veamos ahora algunos detalles de su uso.</p>\n<p>Cuando asignamos el valor, realmente este devuelve 2, el contenido que queremos sacar y si existe o no. Veamoslo con un ejemplo:</p>\n<pre><code>rangerRojo := map[string]int{\n  &quot;Fuerza&quot;: 10000,\n}\n\nrangerVerde := make(map[string]int)\n\npower, exist := rangerRojo[&quot;Fuerza&quot;]\nfmt.Println(&quot;Valor: &quot;, power, &quot;Existe: &quot;, exist)\n\npower2, exist2 := rangerVerde[&quot;Fuerza&quot;]\nfmt.Println(&quot;Valor: &quot;, power2, &quot;Existe: &quot;, exist2)\n</code></pre>\n<p>He usado dos formas de crear maps y el resultado de esto seria:</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-20-at-21.08.38.png\" alt=\"Map Exist or Not\"><br>\nComo veis nos inicializa el valor como suele hacer Go y nos indica que no existe realmente.</p>\n<h2 id=\"borrandocontenidodeunmap\">Borrando contenido de un Map</h2>\n<p>En este caso Go se vuelve muy útil tiene una función propia para poder eliminar el elemento que queramos:</p>\n<pre><code>delete(rangerRojo,&quot;Fuerza&quot;)\n</code></pre>\n<p>Probémoslo en un ejemplo más completo:</p>\n<pre><code>rangerRojo := map[string]int{\n\t&quot;Fuerza&quot;:      10000,\n\t&quot;Resistencia&quot;: 500,\n}\nfmt.Println(rangerRojo)\n\ndelete(rangerRojo, &quot;Fuerza&quot;)\n\nfmt.Println(rangerRojo)\n</code></pre>\n<p>Y como vemos elimina el contenido sin problemas:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-20-at-21.16.50.png\" alt=\"Delete in Maps\"></p>\n<h2 id=\"recorrerunmap\">Recorrer un MAP</h2>\n<p>Para recorrer un MAP usamos la misma teoría que para los <strong>arrays</strong> o <strong>slices</strong>: <strong>RANGE</strong> vamos directos al ejemplo ya que es bastante simple:</p>\n<pre><code>rangerRojo := map[string]interface{}{\n  &quot;Fuerza&quot;:       10000,\n  &quot;Resistencia&quot;:  500,\n  &quot;Inteligencia&quot;: &quot;200&quot;,\n  &quot;Arma&quot;:         &quot;Espada&quot;,\n}\n\nfor key, value := range rangerRojo {\n  fmt.Println(&quot;Clave: &quot;, key, &quot; Valor: &quot;, value)\n}\n</code></pre>\n<p>Tenemos un <strong>map</strong> que tiene como <strong>claves</strong> varios strings representando las características de nuestro ranger y como <strong>valor</strong> he introducido algo que no habiamos visto todavia <strong>INTERFACE{}</strong>, bueno como resumen haceros a la idea de que es un tipo especial que funciona como un genérico, es decir, que representa cualquier valor(por eso podemos tener valores tipo <strong>INT</strong> y tipo <strong>STRING</strong>) y al recorrerlo tenemos esto:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-20-at-21.34.29.png\" alt=\"Range over Map\"><br>\n<span style=\"color:red\">OJO a tener en cuenta, no tiene porque hacerlo en orden sobretodo si introducimos algo a posteriori</span>, mirar un ejemplo:</p>\n<pre><code>rangerRojo := map[string]interface{}{\n  &quot;Fuerza&quot;:       10000,\n  &quot;Resistencia&quot;:  500,\n  &quot;Inteligencia&quot;: 150,\n  &quot;Arma&quot;:         &quot;Espada&quot;,\n}\n\nrangerRojo[&quot;Maná&quot;] = 150\n\nfor key, value := range rangerRojo {\n  fmt.Println(&quot;Clave: &quot;, key, &quot; Valor: &quot;, value)\n}\n</code></pre>\n<p>He añadido otra propiedad a nuestro ranger y el resultado es:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-20-at-21.39.11.png\" alt=\"First random range test\"></p>\n<p>Si lo ejecuto de nuevo:</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-20-at-21.40.10.png\" alt=\"Second random range test\"></p>\n<p>Por último y como he adelantado en el ejemplo anterior:</p>\n<h2 id=\"aadirelementosanuestromap\">Añadir elementos a nuestro MAP</h2>\n<p>Bueno como ya hemos visto esto es muy sencillo:</p>\n<pre><code>rangerRojo[&quot;Maná&quot;] = 150\n\nfmt.Println(rangerRojo)\n</code></pre>\n<p>Y nos muestra<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-20-at-21.43.26.png\" alt=\"Print add content to map\"><br>\nPor el momento hemos terminado con los mapas, profundizaremos en el trabajo con ellos más adelante.<br>\nSin mucho más nos vemos en la siguiente superNinjas :)</p>\n<!--kg-card-end: markdown-->","url":"https://jlgarcia.fulldev.ninja/go-go-power-ra-ah-que-no-go-parte-5-maps/","canonical_url":null,"uuid":"1dac295a-40d7-46d0-a459-2a33030577e4","codeinjection_foot":null,"codeinjection_head":null,"codeinjection_styles":null,"comment_id":"35","reading_time":3,"send_email_when_published":false,"email_subject":null,"childHtmlRehype":{"html":"<!--kg-card-begin: markdown--><p>Espero que este post sea bastante rápido jejejejej.<br>\nEn este caso hablaremos de los <strong>Maps</strong> o lo que en otros lenguajes conoceríamos como diccionario. En general siguen las mismas teorías que los <strong>arrays</strong> o los <strong>slices</strong> en cuanto a creación y a lo referente al rendimiento, los mapas crecen dinámicamente pero podemos indicarles el tamaño lo que optimizaría un poco su rendimiento.</p>\n<h1 id=\"creacin\">Creación</h1>\n<p>Empecemos con la creación. Como ya hemos visto en Go tenemos siempre varias formas de crear los elementos:</p>\n<ul>\n<li>Forma básica</li>\n</ul>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">//var nombreVariable map[tipoClave]tipoValor\nvar rangerRojo map[string]int\n</code></pre></div>\n<ul>\n<li>Declaración corta:</li>\n</ul>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">//Inicializando sin valores\nrangerRojo := map[string]int{}\n\n//Inicializando con valores. Obligatoria la coma ultima\nrangerVerde := map[string]int{\n \"Fuerza\": 10000,\n \"Resistencia\": 5000,\n}\n</code></pre></div>\n<ul>\n<li>Usando <strong>make</strong></li>\n</ul>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">rangerVerde := make(map[string]int)\n//Al igual que en los arrays podemos indicar el tamaño para optimizar rendimiento.\nrangerNegro := make(map[string]int, 2)  \n</code></pre></div>\n<h1 id=\"usandomap\">Usando Map</h1>\n<p>Ya hemos visto un poco como es la creación de <strong>Maps</strong> en golang, no es muy complicado no?, veamos ahora algunos detalles de su uso.</p>\n<p>Cuando asignamos el valor, realmente este devuelve 2, el contenido que queremos sacar y si existe o no. Veamoslo con un ejemplo:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">rangerRojo := map[string]int{\n  \"Fuerza\": 10000,\n}\n\nrangerVerde := make(map[string]int)\n\npower, exist := rangerRojo[\"Fuerza\"]\nfmt.Println(\"Valor: \", power, \"Existe: \", exist)\n\npower2, exist2 := rangerVerde[\"Fuerza\"]\nfmt.Println(\"Valor: \", power2, \"Existe: \", exist2)\n</code></pre></div>\n<p>He usado dos formas de crear maps y el resultado de esto seria:</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-20-at-21.08.38.png\" alt=\"Map Exist or Not\"><br>\nComo veis nos inicializa el valor como suele hacer Go y nos indica que no existe realmente.</p>\n<h2 id=\"borrandocontenidodeunmap\">Borrando contenido de un Map</h2>\n<p>En este caso Go se vuelve muy útil tiene una función propia para poder eliminar el elemento que queramos:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">delete(rangerRojo,\"Fuerza\")\n</code></pre></div>\n<p>Probémoslo en un ejemplo más completo:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">rangerRojo := map[string]int{\n\t\"Fuerza\":      10000,\n\t\"Resistencia\": 500,\n}\nfmt.Println(rangerRojo)\n\ndelete(rangerRojo, \"Fuerza\")\n\nfmt.Println(rangerRojo)\n</code></pre></div>\n<p>Y como vemos elimina el contenido sin problemas:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-20-at-21.16.50.png\" alt=\"Delete in Maps\"></p>\n<h2 id=\"recorrerunmap\">Recorrer un MAP</h2>\n<p>Para recorrer un MAP usamos la misma teoría que para los <strong>arrays</strong> o <strong>slices</strong>: <strong>RANGE</strong> vamos directos al ejemplo ya que es bastante simple:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">rangerRojo := map[string]interface{}{\n  \"Fuerza\":       10000,\n  \"Resistencia\":  500,\n  \"Inteligencia\": \"200\",\n  \"Arma\":         \"Espada\",\n}\n\nfor key, value := range rangerRojo {\n  fmt.Println(\"Clave: \", key, \" Valor: \", value)\n}\n</code></pre></div>\n<p>Tenemos un <strong>map</strong> que tiene como <strong>claves</strong> varios strings representando las características de nuestro ranger y como <strong>valor</strong> he introducido algo que no habiamos visto todavia <strong>INTERFACE{}</strong>, bueno como resumen haceros a la idea de que es un tipo especial que funciona como un genérico, es decir, que representa cualquier valor(por eso podemos tener valores tipo <strong>INT</strong> y tipo <strong>STRING</strong>) y al recorrerlo tenemos esto:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-20-at-21.34.29.png\" alt=\"Range over Map\"><br>\n<span style=\"color:red\">OJO a tener en cuenta, no tiene porque hacerlo en orden sobretodo si introducimos algo a posteriori</span>, mirar un ejemplo:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">rangerRojo := map[string]interface{}{\n  \"Fuerza\":       10000,\n  \"Resistencia\":  500,\n  \"Inteligencia\": 150,\n  \"Arma\":         \"Espada\",\n}\n\nrangerRojo[\"Maná\"] = 150\n\nfor key, value := range rangerRojo {\n  fmt.Println(\"Clave: \", key, \" Valor: \", value)\n}\n</code></pre></div>\n<p>He añadido otra propiedad a nuestro ranger y el resultado es:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-20-at-21.39.11.png\" alt=\"First random range test\"></p>\n<p>Si lo ejecuto de nuevo:</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-20-at-21.40.10.png\" alt=\"Second random range test\"></p>\n<p>Por último y como he adelantado en el ejemplo anterior:</p>\n<h2 id=\"aadirelementosanuestromap\">Añadir elementos a nuestro MAP</h2>\n<p>Bueno como ya hemos visto esto es muy sencillo:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">rangerRojo[\"Maná\"] = 150\n\nfmt.Println(rangerRojo)\n</code></pre></div>\n<p>Y nos muestra<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-20-at-21.43.26.png\" alt=\"Print add content to map\"><br>\nPor el momento hemos terminado con los mapas, profundizaremos en el trabajo con ellos más adelante.<br>\nSin mucho más nos vemos en la siguiente superNinjas :)</p>\n<!--kg-card-end: markdown-->","htmlAst":{"type":"root","children":[{"type":"comment","value":"kg-card-begin: markdown"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Espero que este post sea bastante rápido jejejejej."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nEn este caso hablaremos de los "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Maps"}]},{"type":"text","value":" o lo que en otros lenguajes conoceríamos como diccionario. En general siguen las mismas teorías que los "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"arrays"}]},{"type":"text","value":" o los "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"slices"}]},{"type":"text","value":" en cuanto a creación y a lo referente al rendimiento, los mapas crecen dinámicamente pero podemos indicarles el tamaño lo que optimizaría un poco su rendimiento."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h1","properties":{"id":"creacin"},"children":[{"type":"text","value":"Creación"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Empecemos con la creación. Como ya hemos visto en Go tenemos siempre varias formas de crear los elementos:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Forma básica"}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"//var nombreVariable map[tipoClave]tipoValor\nvar rangerRojo map[string]int\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Declaración corta:"}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"//Inicializando sin valores\nrangerRojo := map[string]int{}\n\n//Inicializando con valores. Obligatoria la coma ultima\nrangerVerde := map[string]int{\n \"Fuerza\": 10000,\n \"Resistencia\": 5000,\n}\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Usando "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"make"}]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"rangerVerde := make(map[string]int)\n//Al igual que en los arrays podemos indicar el tamaño para optimizar rendimiento.\nrangerNegro := make(map[string]int, 2)  \n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h1","properties":{"id":"usandomap"},"children":[{"type":"text","value":"Usando Map"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Ya hemos visto un poco como es la creación de "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Maps"}]},{"type":"text","value":" en golang, no es muy complicado no?, veamos ahora algunos detalles de su uso."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Cuando asignamos el valor, realmente este devuelve 2, el contenido que queremos sacar y si existe o no. Veamoslo con un ejemplo:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"rangerRojo := map[string]int{\n  \"Fuerza\": 10000,\n}\n\nrangerVerde := make(map[string]int)\n\npower, exist := rangerRojo[\"Fuerza\"]\nfmt.Println(\"Valor: \", power, \"Existe: \", exist)\n\npower2, exist2 := rangerVerde[\"Fuerza\"]\nfmt.Println(\"Valor: \", power2, \"Existe: \", exist2)\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"He usado dos formas de crear maps y el resultado de esto seria:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-20-at-21.08.38.png","alt":"Map Exist or Not"},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nComo veis nos inicializa el valor como suele hacer Go y nos indica que no existe realmente."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"borrandocontenidodeunmap"},"children":[{"type":"text","value":"Borrando contenido de un Map"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"En este caso Go se vuelve muy útil tiene una función propia para poder eliminar el elemento que queramos:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"delete(rangerRojo,\"Fuerza\")\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Probémoslo en un ejemplo más completo:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"rangerRojo := map[string]int{\n\t\"Fuerza\":      10000,\n\t\"Resistencia\": 500,\n}\nfmt.Println(rangerRojo)\n\ndelete(rangerRojo, \"Fuerza\")\n\nfmt.Println(rangerRojo)\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Y como vemos elimina el contenido sin problemas:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-20-at-21.16.50.png","alt":"Delete in Maps"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"recorrerunmap"},"children":[{"type":"text","value":"Recorrer un MAP"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Para recorrer un MAP usamos la misma teoría que para los "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"arrays"}]},{"type":"text","value":" o "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"slices"}]},{"type":"text","value":": "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"RANGE"}]},{"type":"text","value":" vamos directos al ejemplo ya que es bastante simple:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"rangerRojo := map[string]interface{}{\n  \"Fuerza\":       10000,\n  \"Resistencia\":  500,\n  \"Inteligencia\": \"200\",\n  \"Arma\":         \"Espada\",\n}\n\nfor key, value := range rangerRojo {\n  fmt.Println(\"Clave: \", key, \" Valor: \", value)\n}\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Tenemos un "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"map"}]},{"type":"text","value":" que tiene como "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"claves"}]},{"type":"text","value":" varios strings representando las características de nuestro ranger y como "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"valor"}]},{"type":"text","value":" he introducido algo que no habiamos visto todavia "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"INTERFACE{}"}]},{"type":"text","value":", bueno como resumen haceros a la idea de que es un tipo especial que funciona como un genérico, es decir, que representa cualquier valor(por eso podemos tener valores tipo "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"INT"}]},{"type":"text","value":" y tipo "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"STRING"}]},{"type":"text","value":") y al recorrerlo tenemos esto:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-20-at-21.34.29.png","alt":"Range over Map"},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"style":"color:red"},"children":[{"type":"text","value":"OJO a tener en cuenta, no tiene porque hacerlo en orden sobretodo si introducimos algo a posteriori"}]},{"type":"text","value":", mirar un ejemplo:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"rangerRojo := map[string]interface{}{\n  \"Fuerza\":       10000,\n  \"Resistencia\":  500,\n  \"Inteligencia\": 150,\n  \"Arma\":         \"Espada\",\n}\n\nrangerRojo[\"Maná\"] = 150\n\nfor key, value := range rangerRojo {\n  fmt.Println(\"Clave: \", key, \" Valor: \", value)\n}\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"He añadido otra propiedad a nuestro ranger y el resultado es:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-20-at-21.39.11.png","alt":"First random range test"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Si lo ejecuto de nuevo:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-20-at-21.40.10.png","alt":"Second random range test"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Por último y como he adelantado en el ejemplo anterior:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"aadirelementosanuestromap"},"children":[{"type":"text","value":"Añadir elementos a nuestro MAP"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Bueno como ya hemos visto esto es muy sencillo:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"rangerRojo[\"Maná\"] = 150\n\nfmt.Println(rangerRojo)\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Y nos muestra"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-20-at-21.43.26.png","alt":"Print add content to map"},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nPor el momento hemos terminado con los mapas, profundizaremos en el trabajo con ellos más adelante."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nSin mucho más nos vemos en la siguiente superNinjas :)"}]},{"type":"text","value":"\n"},{"type":"comment","value":"kg-card-end: markdown"}],"data":{"quirksMode":false}},"tableOfContents":[{"id":"creacin","heading":"Creación"},{"id":"usandomap","heading":"Usando Map","items":[{"id":"borrandocontenidodeunmap","heading":"Borrando contenido de un Map"},{"id":"recorrerunmap","heading":"Recorrer un MAP"},{"id":"aadirelementosanuestromap","heading":"Añadir elementos a nuestro MAP"}]}]},"featureImageSharp":{"base":"Untitled-2.png","publicURL":"/static/4c2a69b59a578389653f7d3cb966f439/Untitled-2.png","imageMeta":{"width":649,"height":244},"childImageSharp":{"fluid":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAABr0lEQVQoz22RPWhTURiGP+29N/eec3/aK1FjI9RBm3aSSBVBDVSzOGpwiMEhKopmsCnYyUVQwS5WxKU6iGBwdOrQqZOD+EO1HYo/mCBtySSC6+O5CQVjHF7ecw7veb6Xc0RrTa8USnV9S57ZZ2LF3rTqeBwqhiIf3++X9AO3YN11AlfGx7KKyTGX4nhXx/YJg9pGZBuOYxs5WJbVC1QdQBfm6oAwCnl+wWFixDMXPbZbGjulicx58dQko6MHKBQK5HK5jvL5/D8NDcz3NQOO4khGaJSElxXh4knFiaMZTh/22b/HwbYdpms1zpVKTNXrlMtlKpUK1Wq1v2ECVdrHPVPi+N0pns2eZ/7FNFdeP+FVY4a5xzfZcf8BA9fr7B4eZjCKSKfTZLNZ4jj+D9B1CXbuQu495OzaBt/ffWJh5RvF5m9azTbrq2tMfN1E5uZRQYhn8q7nkUql8Iz3ApN2QUAggly6xsjndRY32zz68J6Dtcs8ffuG280NrC9trOpVfJPTYdjzoX1vmEzVJmjfmEFaP5HlJoeWllhuzFJYXEA+tpAfv7Bu3enkkrz6i/EHdxf7UmCHE+cAAAAASUVORK5CYII=","aspectRatio":2.6530612244897958,"src":"/static/4c2a69b59a578389653f7d3cb966f439/d382d/Untitled-2.png","srcSet":"/static/4c2a69b59a578389653f7d3cb966f439/bcfcb/Untitled-2.png 260w,\n/static/4c2a69b59a578389653f7d3cb966f439/19d75/Untitled-2.png 520w,\n/static/4c2a69b59a578389653f7d3cb966f439/d382d/Untitled-2.png 649w","srcWebp":"/static/4c2a69b59a578389653f7d3cb966f439/10386/Untitled-2.webp","srcSetWebp":"/static/4c2a69b59a578389653f7d3cb966f439/dc8f3/Untitled-2.webp 260w,\n/static/4c2a69b59a578389653f7d3cb966f439/2db4b/Untitled-2.webp 520w,\n/static/4c2a69b59a578389653f7d3cb966f439/10386/Untitled-2.webp 649w","sizes":"(max-width: 649px) 100vw, 649px"}}}},"prev":{"id":"Ghost__Post__5a338158333e0f134c248f1a","title":"React Superhero : Introducción","slug":"react-superhero-introduccion","featured":false,"feature_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/08/Captain-Atom.jpg","excerpt":"Empiezo nueva sección en el blog (tenía muchísimas ganas de empezar con React).\n\nOs cuento un poco que es esto:\n\n * Esta desarrollado por Facebook que aunque no lo parezca nos da algo de\n   confianza en cuanto a su durabilidad a la larga y su estabilidad.\n * Se centra mucho en la parte de UI, es decir seria la V del MVC.\n * Es muy útil para construir grandes aplicaciones que cambian con el tiempo.\n * Gracias a su Virtual DOM el rendimiento no se ve severamente afectado cuando\n   la información n","custom_excerpt":null,"visibility":"public","created_at_pretty":"29 Jul 2017","published_at_pretty":"7 Aug 2017","updated_at_pretty":"11 Oct 2017","created_at":"2017-07-29T11:24:17.000+02:00","published_at":"2017-08-07T17:33:00.000+02:00","updated_at":"2017-10-11T13:47:25.000+02:00","meta_title":null,"meta_description":null,"og_description":null,"og_image":null,"og_title":null,"twitter_description":null,"twitter_image":null,"twitter_title":null,"authors":[{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":null}],"primary_author":{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":{"base":"Perfil.jpg","publicURL":"/static/b0de6281fb28a266510b3b09b9243e5a/Perfil.jpg","imageMeta":{"width":307,"height":307},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAUDBAb/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAGzw6zC6zHn+cLYP//EAB0QAAICAQUAAAAAAAAAAAAAAAEDAAIEEyEiIzL/2gAIAQEAAQUCifca8KgcKWVfUpkHsG5pxX//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/AR//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/AR//xAAdEAACAgEFAAAAAAAAAAAAAAAAARARcQISIUFR/9oACAEBAAY/AhU88xkb7N06a8P/xAAcEAEAAwEAAwEAAAAAAAAAAAABABEhMUFRYXH/2gAIAQEAAT8hR2pq40aqb+xIAeXibhW9JXr8joF4TBcSNe0//9oADAMBAAIAAwAAABDzDwD/xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/EB//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/EB//xAAcEAEAAgIDAQAAAAAAAAAAAAABABEhUTFhcfD/2gAIAQEAAT8QyItrELaTlatLwU63MvEW6vUNdy4LZQDn7iVApV9VLtANdWwKkuYq4Er1VZ//2Q==","aspectRatio":1,"src":"/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg","srcSet":"/static/b0de6281fb28a266510b3b09b9243e5a/f340b/Perfil.jpg 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/22d64/Perfil.jpg 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/aa249/Perfil.jpg 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/0dc33/Perfil.jpg 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/60667/Perfil.jpg 307w","srcWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp","srcSetWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/59cda/Perfil.webp 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/7da75/Perfil.webp 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f282e/Perfil.webp 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/a7b21/Perfil.webp 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f59af/Perfil.webp 307w","sizes":"(max-width: 110px) 100vw, 110px"}}}},"primary_tag":{"slug":"reactjs","url":"https://jlgarcia.fulldev.ninja/tag/reactjs/","name":"reactjs","visibility":"public","feature_image":null,"description":null,"meta_title":"ReactJS Ninjas","meta_description":"Aprenderemos a usar esta estupenda librería que nos permite desarrollar con un estilo basado en componentes y centrándonse en tener los datos sincronizados","featureImageSharp":null},"tags":[{"slug":"reactjs","url":"https://jlgarcia.fulldev.ninja/tag/reactjs/","name":"reactjs","visibility":"public","feature_image":null,"description":null,"meta_title":"ReactJS Ninjas","meta_description":"Aprenderemos a usar esta estupenda librería que nos permite desarrollar con un estilo basado en componentes y centrándonse en tener los datos sincronizados","featureImageSharp":null}],"plaintext":"Empiezo nueva sección en el blog (tenía muchísimas ganas de empezar con React).\n\nOs cuento un poco que es esto:\n\n * Esta desarrollado por Facebook que aunque no lo parezca nos da algo de\n   confianza en cuanto a su durabilidad a la larga y su estabilidad.\n * Se centra mucho en la parte de UI, es decir seria la V del MVC.\n * Es muy útil para construir grandes aplicaciones que cambian con el tiempo.\n * Gracias a su Virtual DOM el rendimiento no se ve severamente afectado cuando\n   la información necesita actualizarse.\n * Se basa en componentes, haciéndolos reutilizables fácilmente.\n * Lo podemos integrar a cualquier API.\n * Y es JavaScript :)\n * Se puede integrar con Node, Ruby o cualquier otro lenguaje de backend.\n * Tiene framework para mobile (React Native, que lo venden como 'nativo'), que\n   será lo siguiente que veremos cuando terminemos con el básico ;)\n * Usa JSX que es una especie de lenguaje tipo XML para crear nuestros\n   componentes. Básicamente nos permite usar código HTML en variables de JS.\n   Tenéis mas información sobre esto en la pagina oficial de React\n   [https://facebook.github.io/react/docs/introducing-jsx.html].\n\nSuena bien no?? A mi me encanta:\n\n\nPara trabajar con React necesitamos agregar mínimo 3 librerías a nuestro\nproyecto, es decir a nuestro index.html\n\n<!-- Libreria para trabajar con React -->\n<script src=\"https://unpkg.com/react@latest/dist/react.js\"></script>\n<!-- Libreria de react para trabajar con el Dom-->\n<script src=\"https://unpkg.com/react-dom@latest/dist/react-dom.js\"></script>\n<!--Preprocesador para traducir lo que escribimos a todos los navegadores ya que react funciona con ECS6 y puede que no funcione en todos -->\n<script src=\"https://unpkg.com/babel-standalone@6.15.0/babel.min.js\"></script>\n\n\nBien con esto ya tenemos lo básico para trabajar con React. Como extra yo me\ndescargado un plugin para Visual Studio Code para que reconozca el trabajo con\nbabel en su momento. No es en absoluto necesario.\n\nPues bien antes de continuar hagamos una prueba para comprobar que todo funciona\nbien, si alguno ha trabajado o conoce un poco Angular vera como ciertos\nconceptos con parecidos.\n\nVamos a añadir una cabecera a nuestro fichero HTML usando React, para ello\nincluimos lo siguiente:\n\n<script type=\"text/babel\">\n        ReactDOM.render(\n          <h2>Hello with React</h2>,\n          document.getElementById('root');\n        );\n</script>\n\n\nComo vemos usamos en lugar de nuestro text/javascript típico, hemos puesto babel \npara que reconozca que tiene que usar babel. Y a continuación le indicamos que\nrenderice en nuestro DOM el HTML que le pasamos, pero......¿donde? bien aquí es\ndonde viene un concepto similar a angular. En Angular 1.5 por ejemplo teníamos\nnuestro ng-app:\n\n<body ng-app=\"appName\">\n\n\nDonde le indicabamos donde empezaba a funcionar nuestra WebAPP, pues con React\nel concepto es parecido, si veis en el código superior hemos puesto que busque\nun elemento con el ID root(que podria ser cualquier otro nombre), que sera donde\nrenderice el código, por lo que en algún sitio de nuestro código html tenemos\nque añadirlo jejejejje\n\n<div id=\"root\"></div>\n\n\nBien y si todo ha ido bien tendríamos que tener algo similar a esto:\n\nPerfecto, como prueba de concepto esta bien, pero realmente así no se trabaja\ncon React, es un lenguaje basado en componentes por lo que vamos a empezar por\ncrear nuestro primer componente.\n\nPrimer Componente\nNuestro primer componente solo para ver de una forma rápida y facil como se\nharían, lo crearemos en el mismo index.html, dentro de nuestra etiqueta script\n\n<script type=\"text/babel\">\nclass Supercomponente extends React.Component{\n      render(){\n          return <h2>Hello with React</h2>;\n      }\n}\n\n\nComo veis hemos creado una clase Principal (Ojo el nombre tiene que empezar en\nmayúsculas mas abajo veremos porque, y normalmente usamos inglés para los\nnombres, solo he puesto ese superNombre para que quede claro), la cual extiende\nde React.Component. Luego simplemente creamos un método render que devuelve el\nmismo código que teníamos antes, pero... y como lo llamamos, bien aqui viene el\nporque de las mayúsculas al crear el componente.\nLos componentes pasan a ser etiquetas al estilo HTML y las ponemos en mayúsculas\npara diferenciarlas de las etiquetas normales, quedando la llamada al componente\nde esta manera:\n\nReactDOM.render(\n   <SuperComponente/>,\n   document.getElementById('root')\n);\n\n\nPonemos la etiqueta (importante cerrándola al final), y con esto debería\nfuncionarnos igual que antes, y ya habríamos creado y usado nuestro primer\ncomponente.\n\nFácil verdad? Bien como importante recordar que un componente siempre tiene que\ntener un método render y que en las llamadas del ReactDOM, solo repito solo \npodemos pasarle un componente. Y ahora viene cuando nos deberíamos preguntar, ¿Y\ncomo hago para usar varios componentes unos con otros?¿No me digas que tenemos\nque hacer para todos un ReactDOM.render?......Pues no, no es necesario,\nrealmente podemos integrar unos componentes con otros, pero a nivel de\ncomponentes, es decir, un componente puede tener y devolver otros componentes,\nvamos a crear otro componente y hagamos la prueba\n\nclass MiSegundoComponente extends React.Component{\n       render(){\n            return <h2>REACT is in the HOUSE...YEAH!!!!</h2>\n       }\n}\n\n\nYa tenemos otro componente y para llamarlo, lo hacemos desde el primero como si\nde otra etiqueta HTML normal se tratara, algo así no?:\n\nclass SuperComponente extends React.Component{\nrender(){\n     return (\n            <h2>Hello with React</h2>\n            <MiSegundoComponente/>\n        );\n     }\n}\n\n\nFijaros que en el return he metido el contenido entre (), pero hagamos la\nprueba.....upssss no carga nada y si abrimos la consola del navegador vemos lo\nsiguiente:\n\nBien he puesto este error a propósito para que lo tengamos en cuenta como\nimportante, TODOS LOS COMPONENTES ES NECESARIO QUE ESTEN DENTRO DE UNA ETIQUETA\nPADRE, es decir tienen que ser elementos HTML por si solos. En este caso seria\nsimplemente meterlo todo dentro de un div:\n\nclass SuperComponente extends React.Component{\n  render(){\n         return (\n           <div>\n             <h2>Hello with React</h2>\n             <MiSegundoComponente/>\n           </div>\n        );\n   }\n }\n\n\nY ahora ya si nos funcionaria:\n\n\nComo véis el uso de React es bastante fácil solo tenemos que tener unas pequeñas\ncosas en cuenta, como por ejemplo que los componentes tengan que estar\nencapsulados dentro de una etiqueta principal para que funcionen.\n\nY hasta aquí este post introductorio de React, os animo a seguir los siguientes\nsi queréis aprender al mismo tiempo que yo a usar React, nos vemos en el\nsiguiente.","html":"<!--kg-card-begin: markdown--><p>Empiezo nueva sección en el blog (tenía muchísimas ganas de empezar con React).</p>\n<p>Os cuento un poco que es esto:</p>\n<ul>\n<li>Esta desarrollado por Facebook que aunque no lo parezca nos da algo de confianza en cuanto a su durabilidad a la larga y su estabilidad.</li>\n<li>Se centra mucho en la parte de UI, es decir seria la V del MVC.</li>\n<li>Es muy útil para construir grandes aplicaciones que cambian con el tiempo.</li>\n<li>Gracias a su <strong>Virtual DOM</strong> el rendimiento no se ve severamente afectado cuando la información necesita actualizarse.</li>\n<li>Se basa en componentes, haciéndolos reutilizables fácilmente.</li>\n<li>Lo podemos integrar a cualquier API.</li>\n<li>Y es JavaScript :)</li>\n<li>Se puede integrar con Node, Ruby o cualquier otro lenguaje de backend.</li>\n<li>Tiene framework para mobile (<strong>React Native</strong>, que lo venden como 'nativo'), que será lo siguiente que veremos cuando terminemos con el básico ;)</li>\n<li>Usa <strong>JSX</strong> que es una especie de lenguaje tipo XML para crear nuestros componentes. Básicamente nos permite usar código HTML en variables de JS. Tenéis mas información sobre esto en la pagina oficial de <a href=\"https://facebook.github.io/react/docs/introducing-jsx.html\">React</a>.</li>\n</ul>\n<p>Suena bien no?? A mi me encanta:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/08/1839631-catom_cv1-1.jpg\" alt=\"Captian Atom\"></p>\n<p>Para trabajar con React necesitamos agregar mínimo 3 librerías a nuestro proyecto, es decir a nuestro index.html</p>\n<pre><code>&lt;!-- Libreria para trabajar con React --&gt;\n&lt;script src=&quot;https://unpkg.com/react@latest/dist/react.js&quot;&gt;&lt;/script&gt;\n&lt;!-- Libreria de react para trabajar con el Dom--&gt;\n&lt;script src=&quot;https://unpkg.com/react-dom@latest/dist/react-dom.js&quot;&gt;&lt;/script&gt;\n&lt;!--Preprocesador para traducir lo que escribimos a todos los navegadores ya que react funciona con ECS6 y puede que no funcione en todos --&gt;\n&lt;script src=&quot;https://unpkg.com/babel-standalone@6.15.0/babel.min.js&quot;&gt;&lt;/script&gt;\n</code></pre>\n<p>Bien con esto ya tenemos lo básico para trabajar con React. Como extra yo me descargado un plugin para <strong>Visual Studio Code</strong> para que reconozca el trabajo con babel en su momento. No es en absoluto necesario.</p>\n<p>Pues bien antes de continuar hagamos una prueba para comprobar que todo funciona bien, si alguno ha trabajado o conoce un poco Angular vera como ciertos conceptos con parecidos.</p>\n<p>Vamos a añadir una cabecera a nuestro fichero HTML usando React, para ello incluimos lo siguiente:</p>\n<pre><code>&lt;script type=&quot;text/babel&quot;&gt;\n        ReactDOM.render(\n          &lt;h2&gt;Hello with React&lt;/h2&gt;,\n          document.getElementById('root');\n        );\n&lt;/script&gt;\n</code></pre>\n<p>Como vemos usamos en lugar de nuestro <strong>text/javascript</strong> típico, hemos puesto <strong>babel</strong> para que reconozca que tiene que usar babel. Y a continuación le indicamos que renderice en nuestro DOM el HTML que le pasamos, pero......¿donde? bien aquí es donde viene un concepto similar a angular. En Angular 1.5 por ejemplo teníamos nuestro ng-app:</p>\n<pre><code>&lt;body ng-app=&quot;appName&quot;&gt;\n</code></pre>\n<p>Donde le indicabamos donde empezaba a funcionar nuestra WebAPP, pues con React el concepto es parecido, si veis en el código superior hemos puesto que busque un elemento con el ID <strong>root</strong>(que podria ser cualquier otro nombre), que sera donde renderice el código, por lo que en algún sitio de nuestro código html tenemos que añadirlo jejejejje</p>\n<pre><code>&lt;div id=&quot;root&quot;&gt;&lt;/div&gt;\n</code></pre>\n<p>Bien y si todo ha ido bien tendríamos que tener algo similar a esto:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-29-at-14.23.56.png\" alt=\"React Hello\"><br>\nPerfecto, como prueba de concepto esta bien, pero realmente así no se trabaja con React, es un lenguaje basado en componentes por lo que vamos a empezar por crear nuestro primer componente.</p>\n<h2 id=\"primercomponente\">Primer Componente</h2>\n<p>Nuestro primer componente solo para ver de una forma rápida y facil como se harían, lo crearemos en el mismo index.html, dentro de nuestra etiqueta <strong>script</strong></p>\n<pre><code>&lt;script type=&quot;text/babel&quot;&gt;\nclass Supercomponente extends React.Component{\n      render(){\n          return &lt;h2&gt;Hello with React&lt;/h2&gt;;\n      }\n}\n</code></pre>\n<p>Como veis hemos creado una clase <strong>Principal (Ojo el nombre tiene que empezar en mayúsculas mas abajo veremos porque, y normalmente usamos inglés para los nombres, solo he puesto ese superNombre para que quede claro)</strong>, la cual extiende de <strong>React.Component</strong>. Luego simplemente creamos un método <strong>render</strong> que devuelve el mismo código que teníamos antes, pero... y como lo llamamos, bien aqui viene el porque de las <strong>mayúsculas</strong> al crear el componente.<br>\nLos componentes pasan a ser etiquetas al estilo HTML y las ponemos en mayúsculas para diferenciarlas de las etiquetas normales, quedando la llamada al componente de esta manera:</p>\n<pre><code>ReactDOM.render(\n   &lt;SuperComponente/&gt;,\n   document.getElementById('root')\n);\n</code></pre>\n<p>Ponemos la etiqueta (importante cerrándola al final), y con esto debería funcionarnos igual que antes, y ya habríamos creado y usado nuestro primer componente.</p>\n<p>Fácil verdad?  Bien como importante recordar que un componente siempre tiene que tener un método <strong>render</strong> y que en las llamadas del ReactDOM, solo repito <strong>solo</strong> podemos pasarle un componente. Y ahora viene cuando nos deberíamos preguntar, ¿Y como hago para usar varios componentes unos con otros?¿No me digas que tenemos que hacer para todos un <strong>ReactDOM.render</strong>?......Pues no, no es necesario, realmente podemos integrar unos componentes con otros, pero a nivel de componentes, es decir, un componente puede tener y devolver otros componentes, vamos a crear otro componente y hagamos la prueba</p>\n<pre><code>class MiSegundoComponente extends React.Component{\n       render(){\n            return &lt;h2&gt;REACT is in the HOUSE...YEAH!!!!&lt;/h2&gt;\n       }\n}\n</code></pre>\n<p>Ya tenemos otro componente y para llamarlo, lo hacemos desde el primero como si de otra etiqueta HTML normal se tratara, algo así no?:</p>\n<pre><code>class SuperComponente extends React.Component{\nrender(){\n     return (\n            &lt;h2&gt;Hello with React&lt;/h2&gt;\n            &lt;MiSegundoComponente/&gt;\n        );\n     }\n}\n</code></pre>\n<p>Fijaros que en el return he metido el contenido entre <strong>()</strong>, pero hagamos la prueba.....upssss no carga nada y si abrimos la consola del navegador vemos lo siguiente:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-29-at-19.08.39.png\" alt=\"Error component\"><br>\nBien he puesto este error a propósito para que lo tengamos en cuenta como importante, <strong>TODOS LOS COMPONENTES ES NECESARIO QUE ESTEN DENTRO DE UNA ETIQUETA PADRE</strong>, es decir tienen que ser elementos HTML por si solos. En este caso seria simplemente meterlo todo dentro de un <strong>div</strong>:</p>\n<pre><code>class SuperComponente extends React.Component{\n  render(){\n         return (\n           &lt;div&gt;\n             &lt;h2&gt;Hello with React&lt;/h2&gt;\n             &lt;MiSegundoComponente/&gt;\n           &lt;/div&gt;\n        );\n   }\n }\n</code></pre>\n<p>Y ahora ya si nos funcionaria:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-29-at-19.13.47.png\" alt=\"Two Components\"></p>\n<p>Como véis el uso de React es bastante fácil solo tenemos que tener unas pequeñas cosas en cuenta, como por ejemplo que los componentes tengan que estar encapsulados dentro de una etiqueta principal para que funcionen.</p>\n<p>Y hasta aquí este post introductorio de React, os animo a seguir los siguientes si queréis aprender al mismo tiempo que yo a usar React, nos vemos en el siguiente.</p>\n<!--kg-card-end: markdown-->","url":"https://jlgarcia.fulldev.ninja/react-superhero-introduccion/","canonical_url":null,"uuid":"82052b61-c7f7-43d3-9925-93d88de7f937","codeinjection_foot":null,"codeinjection_head":null,"codeinjection_styles":null,"comment_id":"39","reading_time":5,"send_email_when_published":false,"email_subject":null,"childHtmlRehype":{"html":"<!--kg-card-begin: markdown--><p>Empiezo nueva sección en el blog (tenía muchísimas ganas de empezar con React).</p>\n<p>Os cuento un poco que es esto:</p>\n<ul>\n<li>Esta desarrollado por Facebook que aunque no lo parezca nos da algo de confianza en cuanto a su durabilidad a la larga y su estabilidad.</li>\n<li>Se centra mucho en la parte de UI, es decir seria la V del MVC.</li>\n<li>Es muy útil para construir grandes aplicaciones que cambian con el tiempo.</li>\n<li>Gracias a su <strong>Virtual DOM</strong> el rendimiento no se ve severamente afectado cuando la información necesita actualizarse.</li>\n<li>Se basa en componentes, haciéndolos reutilizables fácilmente.</li>\n<li>Lo podemos integrar a cualquier API.</li>\n<li>Y es JavaScript :)</li>\n<li>Se puede integrar con Node, Ruby o cualquier otro lenguaje de backend.</li>\n<li>Tiene framework para mobile (<strong>React Native</strong>, que lo venden como 'nativo'), que será lo siguiente que veremos cuando terminemos con el básico ;)</li>\n<li>Usa <strong>JSX</strong> que es una especie de lenguaje tipo XML para crear nuestros componentes. Básicamente nos permite usar código HTML en variables de JS. Tenéis mas información sobre esto en la pagina oficial de <a href=\"https://facebook.github.io/react/docs/introducing-jsx.html\">React</a>.</li>\n</ul>\n<p>Suena bien no?? A mi me encanta:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/08/1839631-catom_cv1-1.jpg\" alt=\"Captian Atom\"></p>\n<p>Para trabajar con React necesitamos agregar mínimo 3 librerías a nuestro proyecto, es decir a nuestro index.html</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">&#x3C;!-- Libreria para trabajar con React -->\n&#x3C;script src=\"https://unpkg.com/react@latest/dist/react.js\">&#x3C;/script>\n&#x3C;!-- Libreria de react para trabajar con el Dom-->\n&#x3C;script src=\"https://unpkg.com/react-dom@latest/dist/react-dom.js\">&#x3C;/script>\n&#x3C;!--Preprocesador para traducir lo que escribimos a todos los navegadores ya que react funciona con ECS6 y puede que no funcione en todos -->\n&#x3C;script src=\"https://unpkg.com/babel-standalone@6.15.0/babel.min.js\">&#x3C;/script>\n</code></pre></div>\n<p>Bien con esto ya tenemos lo básico para trabajar con React. Como extra yo me descargado un plugin para <strong>Visual Studio Code</strong> para que reconozca el trabajo con babel en su momento. No es en absoluto necesario.</p>\n<p>Pues bien antes de continuar hagamos una prueba para comprobar que todo funciona bien, si alguno ha trabajado o conoce un poco Angular vera como ciertos conceptos con parecidos.</p>\n<p>Vamos a añadir una cabecera a nuestro fichero HTML usando React, para ello incluimos lo siguiente:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">&#x3C;script type=\"text/babel\">\n        ReactDOM.render(\n          &#x3C;h2>Hello with React&#x3C;/h2>,\n          document.getElementById('root');\n        );\n&#x3C;/script>\n</code></pre></div>\n<p>Como vemos usamos en lugar de nuestro <strong>text/javascript</strong> típico, hemos puesto <strong>babel</strong> para que reconozca que tiene que usar babel. Y a continuación le indicamos que renderice en nuestro DOM el HTML que le pasamos, pero......¿donde? bien aquí es donde viene un concepto similar a angular. En Angular 1.5 por ejemplo teníamos nuestro ng-app:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">&#x3C;body ng-app=\"appName\">\n</code></pre></div>\n<p>Donde le indicabamos donde empezaba a funcionar nuestra WebAPP, pues con React el concepto es parecido, si veis en el código superior hemos puesto que busque un elemento con el ID <strong>root</strong>(que podria ser cualquier otro nombre), que sera donde renderice el código, por lo que en algún sitio de nuestro código html tenemos que añadirlo jejejejje</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">&#x3C;div id=\"root\">&#x3C;/div>\n</code></pre></div>\n<p>Bien y si todo ha ido bien tendríamos que tener algo similar a esto:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-29-at-14.23.56.png\" alt=\"React Hello\"><br>\nPerfecto, como prueba de concepto esta bien, pero realmente así no se trabaja con React, es un lenguaje basado en componentes por lo que vamos a empezar por crear nuestro primer componente.</p>\n<h2 id=\"primercomponente\">Primer Componente</h2>\n<p>Nuestro primer componente solo para ver de una forma rápida y facil como se harían, lo crearemos en el mismo index.html, dentro de nuestra etiqueta <strong>script</strong></p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">&#x3C;script type=\"text/babel\">\nclass Supercomponente extends React.Component{\n      render(){\n          return &#x3C;h2>Hello with React&#x3C;/h2>;\n      }\n}\n</code></pre></div>\n<p>Como veis hemos creado una clase <strong>Principal (Ojo el nombre tiene que empezar en mayúsculas mas abajo veremos porque, y normalmente usamos inglés para los nombres, solo he puesto ese superNombre para que quede claro)</strong>, la cual extiende de <strong>React.Component</strong>. Luego simplemente creamos un método <strong>render</strong> que devuelve el mismo código que teníamos antes, pero... y como lo llamamos, bien aqui viene el porque de las <strong>mayúsculas</strong> al crear el componente.<br>\nLos componentes pasan a ser etiquetas al estilo HTML y las ponemos en mayúsculas para diferenciarlas de las etiquetas normales, quedando la llamada al componente de esta manera:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">ReactDOM.render(\n   &#x3C;SuperComponente/>,\n   document.getElementById('root')\n);\n</code></pre></div>\n<p>Ponemos la etiqueta (importante cerrándola al final), y con esto debería funcionarnos igual que antes, y ya habríamos creado y usado nuestro primer componente.</p>\n<p>Fácil verdad?  Bien como importante recordar que un componente siempre tiene que tener un método <strong>render</strong> y que en las llamadas del ReactDOM, solo repito <strong>solo</strong> podemos pasarle un componente. Y ahora viene cuando nos deberíamos preguntar, ¿Y como hago para usar varios componentes unos con otros?¿No me digas que tenemos que hacer para todos un <strong>ReactDOM.render</strong>?......Pues no, no es necesario, realmente podemos integrar unos componentes con otros, pero a nivel de componentes, es decir, un componente puede tener y devolver otros componentes, vamos a crear otro componente y hagamos la prueba</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">class MiSegundoComponente extends React.Component{\n       render(){\n            return &#x3C;h2>REACT is in the HOUSE...YEAH!!!!&#x3C;/h2>\n       }\n}\n</code></pre></div>\n<p>Ya tenemos otro componente y para llamarlo, lo hacemos desde el primero como si de otra etiqueta HTML normal se tratara, algo así no?:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">class SuperComponente extends React.Component{\nrender(){\n     return (\n            &#x3C;h2>Hello with React&#x3C;/h2>\n            &#x3C;MiSegundoComponente/>\n        );\n     }\n}\n</code></pre></div>\n<p>Fijaros que en el return he metido el contenido entre <strong>()</strong>, pero hagamos la prueba.....upssss no carga nada y si abrimos la consola del navegador vemos lo siguiente:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-29-at-19.08.39.png\" alt=\"Error component\"><br>\nBien he puesto este error a propósito para que lo tengamos en cuenta como importante, <strong>TODOS LOS COMPONENTES ES NECESARIO QUE ESTEN DENTRO DE UNA ETIQUETA PADRE</strong>, es decir tienen que ser elementos HTML por si solos. En este caso seria simplemente meterlo todo dentro de un <strong>div</strong>:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">class SuperComponente extends React.Component{\n  render(){\n         return (\n           &#x3C;div>\n             &#x3C;h2>Hello with React&#x3C;/h2>\n             &#x3C;MiSegundoComponente/>\n           &#x3C;/div>\n        );\n   }\n }\n</code></pre></div>\n<p>Y ahora ya si nos funcionaria:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-29-at-19.13.47.png\" alt=\"Two Components\"></p>\n<p>Como véis el uso de React es bastante fácil solo tenemos que tener unas pequeñas cosas en cuenta, como por ejemplo que los componentes tengan que estar encapsulados dentro de una etiqueta principal para que funcionen.</p>\n<p>Y hasta aquí este post introductorio de React, os animo a seguir los siguientes si queréis aprender al mismo tiempo que yo a usar React, nos vemos en el siguiente.</p>\n<!--kg-card-end: markdown-->","htmlAst":{"type":"root","children":[{"type":"comment","value":"kg-card-begin: markdown"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Empiezo nueva sección en el blog (tenía muchísimas ganas de empezar con React)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Os cuento un poco que es esto:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Esta desarrollado por Facebook que aunque no lo parezca nos da algo de confianza en cuanto a su durabilidad a la larga y su estabilidad."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Se centra mucho en la parte de UI, es decir seria la V del MVC."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Es muy útil para construir grandes aplicaciones que cambian con el tiempo."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Gracias a su "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Virtual DOM"}]},{"type":"text","value":" el rendimiento no se ve severamente afectado cuando la información necesita actualizarse."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Se basa en componentes, haciéndolos reutilizables fácilmente."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Lo podemos integrar a cualquier API."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Y es JavaScript :)"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Se puede integrar con Node, Ruby o cualquier otro lenguaje de backend."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Tiene framework para mobile ("},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"React Native"}]},{"type":"text","value":", que lo venden como 'nativo'), que será lo siguiente que veremos cuando terminemos con el básico ;)"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Usa "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"JSX"}]},{"type":"text","value":" que es una especie de lenguaje tipo XML para crear nuestros componentes. Básicamente nos permite usar código HTML en variables de JS. Tenéis mas información sobre esto en la pagina oficial de "},{"type":"element","tagName":"a","properties":{"href":"https://facebook.github.io/react/docs/introducing-jsx.html"},"children":[{"type":"text","value":"React"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Suena bien no?? A mi me encanta:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/08/1839631-catom_cv1-1.jpg","alt":"Captian Atom"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Para trabajar con React necesitamos agregar mínimo 3 librerías a nuestro proyecto, es decir a nuestro index.html"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"<!-- Libreria para trabajar con React -->\n<script src=\"https://unpkg.com/react@latest/dist/react.js\"></script>\n<!-- Libreria de react para trabajar con el Dom-->\n<script src=\"https://unpkg.com/react-dom@latest/dist/react-dom.js\"></script>\n<!--Preprocesador para traducir lo que escribimos a todos los navegadores ya que react funciona con ECS6 y puede que no funcione en todos -->\n<script src=\"https://unpkg.com/babel-standalone@6.15.0/babel.min.js\"></script>\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Bien con esto ya tenemos lo básico para trabajar con React. Como extra yo me descargado un plugin para "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Visual Studio Code"}]},{"type":"text","value":" para que reconozca el trabajo con babel en su momento. No es en absoluto necesario."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Pues bien antes de continuar hagamos una prueba para comprobar que todo funciona bien, si alguno ha trabajado o conoce un poco Angular vera como ciertos conceptos con parecidos."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Vamos a añadir una cabecera a nuestro fichero HTML usando React, para ello incluimos lo siguiente:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"<script type=\"text/babel\">\n        ReactDOM.render(\n          <h2>Hello with React</h2>,\n          document.getElementById('root');\n        );\n</script>\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Como vemos usamos en lugar de nuestro "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"text/javascript"}]},{"type":"text","value":" típico, hemos puesto "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"babel"}]},{"type":"text","value":" para que reconozca que tiene que usar babel. Y a continuación le indicamos que renderice en nuestro DOM el HTML que le pasamos, pero......¿donde? bien aquí es donde viene un concepto similar a angular. En Angular 1.5 por ejemplo teníamos nuestro ng-app:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"<body ng-app=\"appName\">\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Donde le indicabamos donde empezaba a funcionar nuestra WebAPP, pues con React el concepto es parecido, si veis en el código superior hemos puesto que busque un elemento con el ID "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"root"}]},{"type":"text","value":"(que podria ser cualquier otro nombre), que sera donde renderice el código, por lo que en algún sitio de nuestro código html tenemos que añadirlo jejejejje"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"<div id=\"root\"></div>\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Bien y si todo ha ido bien tendríamos que tener algo similar a esto:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-29-at-14.23.56.png","alt":"React Hello"},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nPerfecto, como prueba de concepto esta bien, pero realmente así no se trabaja con React, es un lenguaje basado en componentes por lo que vamos a empezar por crear nuestro primer componente."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"primercomponente"},"children":[{"type":"text","value":"Primer Componente"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Nuestro primer componente solo para ver de una forma rápida y facil como se harían, lo crearemos en el mismo index.html, dentro de nuestra etiqueta "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"script"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"<script type=\"text/babel\">\nclass Supercomponente extends React.Component{\n      render(){\n          return <h2>Hello with React</h2>;\n      }\n}\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Como veis hemos creado una clase "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Principal (Ojo el nombre tiene que empezar en mayúsculas mas abajo veremos porque, y normalmente usamos inglés para los nombres, solo he puesto ese superNombre para que quede claro)"}]},{"type":"text","value":", la cual extiende de "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"React.Component"}]},{"type":"text","value":". Luego simplemente creamos un método "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"render"}]},{"type":"text","value":" que devuelve el mismo código que teníamos antes, pero... y como lo llamamos, bien aqui viene el porque de las "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"mayúsculas"}]},{"type":"text","value":" al crear el componente."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nLos componentes pasan a ser etiquetas al estilo HTML y las ponemos en mayúsculas para diferenciarlas de las etiquetas normales, quedando la llamada al componente de esta manera:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"ReactDOM.render(\n   <SuperComponente/>,\n   document.getElementById('root')\n);\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Ponemos la etiqueta (importante cerrándola al final), y con esto debería funcionarnos igual que antes, y ya habríamos creado y usado nuestro primer componente."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Fácil verdad?  Bien como importante recordar que un componente siempre tiene que tener un método "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"render"}]},{"type":"text","value":" y que en las llamadas del ReactDOM, solo repito "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"solo"}]},{"type":"text","value":" podemos pasarle un componente. Y ahora viene cuando nos deberíamos preguntar, ¿Y como hago para usar varios componentes unos con otros?¿No me digas que tenemos que hacer para todos un "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"ReactDOM.render"}]},{"type":"text","value":"?......Pues no, no es necesario, realmente podemos integrar unos componentes con otros, pero a nivel de componentes, es decir, un componente puede tener y devolver otros componentes, vamos a crear otro componente y hagamos la prueba"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"class MiSegundoComponente extends React.Component{\n       render(){\n            return <h2>REACT is in the HOUSE...YEAH!!!!</h2>\n       }\n}\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Ya tenemos otro componente y para llamarlo, lo hacemos desde el primero como si de otra etiqueta HTML normal se tratara, algo así no?:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"class SuperComponente extends React.Component{\nrender(){\n     return (\n            <h2>Hello with React</h2>\n            <MiSegundoComponente/>\n        );\n     }\n}\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Fijaros que en el return he metido el contenido entre "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"()"}]},{"type":"text","value":", pero hagamos la prueba.....upssss no carga nada y si abrimos la consola del navegador vemos lo siguiente:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-29-at-19.08.39.png","alt":"Error component"},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nBien he puesto este error a propósito para que lo tengamos en cuenta como importante, "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"TODOS LOS COMPONENTES ES NECESARIO QUE ESTEN DENTRO DE UNA ETIQUETA PADRE"}]},{"type":"text","value":", es decir tienen que ser elementos HTML por si solos. En este caso seria simplemente meterlo todo dentro de un "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"div"}]},{"type":"text","value":":"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"class SuperComponente extends React.Component{\n  render(){\n         return (\n           <div>\n             <h2>Hello with React</h2>\n             <MiSegundoComponente/>\n           </div>\n        );\n   }\n }\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Y ahora ya si nos funcionaria:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-29-at-19.13.47.png","alt":"Two Components"},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Como véis el uso de React es bastante fácil solo tenemos que tener unas pequeñas cosas en cuenta, como por ejemplo que los componentes tengan que estar encapsulados dentro de una etiqueta principal para que funcionen."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Y hasta aquí este post introductorio de React, os animo a seguir los siguientes si queréis aprender al mismo tiempo que yo a usar React, nos vemos en el siguiente."}]},{"type":"text","value":"\n"},{"type":"comment","value":"kg-card-end: markdown"}],"data":{"quirksMode":false}},"tableOfContents":[{"id":"primercomponente","heading":"Primer Componente"}]},"featureImageSharp":{"base":"Captain-Atom.jpg","publicURL":"/static/ea41313c22f611d45d277d453c4273d1/Captain-Atom.jpg","imageMeta":{"width":864,"height":648},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAQCBv/EABYBAQEBAAAAAAAAAAAAAAAAAAMBAv/aAAwDAQACEAMQAAABojay1bnBz//EABkQAQACAwAAAAAAAAAAAAAAAAECAwARE//aAAgBAQABBQKoAmdchqqPFMlZGuC7f//EABcRAQEBAQAAAAAAAAAAAAAAAAEAEiH/2gAIAQMBAT8BONov/8QAGBEAAgMAAAAAAAAAAAAAAAAAAAERE0H/2gAIAQIBAT8BbK50/8QAHhAAAwAABwEAAAAAAAAAAAAAAAERAhIiMTJRUmH/2gAIAQEABj8C0x9lWxlq+j9ImHkVn//EABkQAQADAQEAAAAAAAAAAAAAAAEAESExQf/aAAgBAQABPyHlOmjsuNqMAiJQe2TspkuwMcZ4otX5GdLXWf/aAAwDAQACAAMAAAAQy/8A/8QAFhEBAQEAAAAAAAAAAAAAAAAAAQBB/9oACAEDAQE/ECLJZf/EABYRAQEBAAAAAAAAAAAAAAAAAAERAP/aAAgBAgEBPxBJcpVz/8QAHBABAAIDAAMAAAAAAAAAAAAAAQARITFBUWHR/9oACAEBAAE/ECGZHOFc9RXVMNQfYPyzYFbcsWTgugFwsFDeqNnrnxyXBPYm2f/Z","aspectRatio":1.3358778625954197,"src":"/static/ea41313c22f611d45d277d453c4273d1/ea4ab/Captain-Atom.jpg","srcSet":"/static/ea41313c22f611d45d277d453c4273d1/477ba/Captain-Atom.jpg 175w,\n/static/ea41313c22f611d45d277d453c4273d1/06776/Captain-Atom.jpg 350w,\n/static/ea41313c22f611d45d277d453c4273d1/ea4ab/Captain-Atom.jpg 700w,\n/static/ea41313c22f611d45d277d453c4273d1/fc1a6/Captain-Atom.jpg 864w","srcWebp":"/static/ea41313c22f611d45d277d453c4273d1/89afa/Captain-Atom.webp","srcSetWebp":"/static/ea41313c22f611d45d277d453c4273d1/9fca7/Captain-Atom.webp 175w,\n/static/ea41313c22f611d45d277d453c4273d1/37a4e/Captain-Atom.webp 350w,\n/static/ea41313c22f611d45d277d453c4273d1/89afa/Captain-Atom.webp 700w,\n/static/ea41313c22f611d45d277d453c4273d1/65e54/Captain-Atom.webp 864w","sizes":"(max-width: 700px) 100vw, 700px"}}}},"next":{"id":"Ghost__Post__5a338158333e0f134c248f13","title":"Cloud Adventures: Android y Azure Active Directory Login","slug":"cloud-adventures-android-y-azure-active-directory-login","featured":false,"feature_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/cloud-ninjaaz.png","excerpt":"Estreno otra sección, en este caso estará centrado en problemas que me he ido\nencontrado con los servicios Cloud a la hora de desarrollar alguna aplicación\nnativa para Android o IOS.\nEn este caso le toca el turno a Azure, por ciertas necesidades he tenido que\n\"pegarme\" con el servicio para que me funcionara el Login con el servicio de\nAzure Active Directory.\nVuelve a ser por el problema de la documentación existente, que creo que es el\núnico problema con los servicios Cloud, que la documentación","custom_excerpt":null,"visibility":"public","created_at_pretty":"12 Jul 2017","published_at_pretty":"19 Jul 2017","updated_at_pretty":"11 Oct 2017","created_at":"2017-07-12T18:20:23.000+02:00","published_at":"2017-07-19T21:39:07.000+02:00","updated_at":"2017-10-11T13:51:23.000+02:00","meta_title":null,"meta_description":null,"og_description":null,"og_image":null,"og_title":null,"twitter_description":null,"twitter_image":null,"twitter_title":null,"authors":[{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":null}],"primary_author":{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":{"base":"Perfil.jpg","publicURL":"/static/b0de6281fb28a266510b3b09b9243e5a/Perfil.jpg","imageMeta":{"width":307,"height":307},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAUDBAb/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAGzw6zC6zHn+cLYP//EAB0QAAICAQUAAAAAAAAAAAAAAAEDAAIEEyEiIzL/2gAIAQEAAQUCifca8KgcKWVfUpkHsG5pxX//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/AR//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/AR//xAAdEAACAgEFAAAAAAAAAAAAAAAAARARcQISIUFR/9oACAEBAAY/AhU88xkb7N06a8P/xAAcEAEAAwEAAwEAAAAAAAAAAAABABEhMUFRYXH/2gAIAQEAAT8hR2pq40aqb+xIAeXibhW9JXr8joF4TBcSNe0//9oADAMBAAIAAwAAABDzDwD/xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/EB//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/EB//xAAcEAEAAgIDAQAAAAAAAAAAAAABABEhUTFhcfD/2gAIAQEAAT8QyItrELaTlatLwU63MvEW6vUNdy4LZQDn7iVApV9VLtANdWwKkuYq4Er1VZ//2Q==","aspectRatio":1,"src":"/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg","srcSet":"/static/b0de6281fb28a266510b3b09b9243e5a/f340b/Perfil.jpg 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/22d64/Perfil.jpg 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/aa249/Perfil.jpg 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/0dc33/Perfil.jpg 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/60667/Perfil.jpg 307w","srcWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp","srcSetWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/59cda/Perfil.webp 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/7da75/Perfil.webp 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f282e/Perfil.webp 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/a7b21/Perfil.webp 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f59af/Perfil.webp 307w","sizes":"(max-width: 110px) 100vw, 110px"}}}},"primary_tag":{"slug":"azure","url":"https://jlgarcia.fulldev.ninja/tag/azure/","name":"azure","visibility":"public","feature_image":null,"description":"Convirtamonos en Ninjas de Azure","meta_title":"Azure Ninjas","meta_description":"Convirtamonos en Ninjas de Azure, viendo algunos de los problemas que nos podemos encontrar en nuestro dia a dia.","featureImageSharp":null},"tags":[{"slug":"azure","url":"https://jlgarcia.fulldev.ninja/tag/azure/","name":"azure","visibility":"public","feature_image":null,"description":"Convirtamonos en Ninjas de Azure","meta_title":"Azure Ninjas","meta_description":"Convirtamonos en Ninjas de Azure, viendo algunos de los problemas que nos podemos encontrar en nuestro dia a dia.","featureImageSharp":null},{"slug":"cloud","url":"https://jlgarcia.fulldev.ninja/tag/cloud/","name":"cloud","visibility":"public","feature_image":null,"description":null,"meta_title":"Cloud Ninjas","meta_description":"Veremos temas relacionados con los tres sistemas cloud más usados: Azure, AWS y Firebase.","featureImageSharp":null},{"slug":"android","url":"https://jlgarcia.fulldev.ninja/tag/android/","name":"android","visibility":"public","feature_image":null,"description":null,"meta_title":"Android Ninja","meta_description":"Post con problemas que me he ido encontrando trabajando con desarrollos para dispositivos Android.","featureImageSharp":null}],"plaintext":"Estreno otra sección, en este caso estará centrado en problemas que me he ido\nencontrado con los servicios Cloud a la hora de desarrollar alguna aplicación\nnativa para Android o IOS.\nEn este caso le toca el turno a Azure, por ciertas necesidades he tenido que\n\"pegarme\" con el servicio para que me funcionara el Login con el servicio de\nAzure Active Directory.\nVuelve a ser por el problema de la documentación existente, que creo que es el\núnico problema con los servicios Cloud, que la documentación o no esta clara o\nno esta actualizada.\n\nEste escenario es muy simple, queremos hacer login, con una app Android, usando\nusuarios pertenecientes a Azure Active Directory, en un principio debería ser\nbastante fácil pero por lo menos en mi caso he tenido algún que otro problema.\n\nPrimero de todo:\n\nConfigurar el AppService para el login\nTeóricamente bastante sencillo, vamos a la doc oficial:\nConfigure AAD in APPService\n[https://docs.microsoft.com/es-es/azure/app-service-mobile/app-service-mobile-how-to-configure-active-directory-authentication]\n\nY la seguimos, como tal hacemos todo y pensamos que todo esta bien, pero a la\nhora de probarlo falta alguna cosilla, que os voy adelantando por aqui:\n\n\n\nComo véis en la foto en las redirecciones URL permitidas necesitamos añadirle\nalgo similar a lo que veis en la foto, básicamente es el nombre de tu appservice \nseguido de un extra:\n\nappservicename://easyauth.callback\n\n\nEsto es importante, lo que pongamos aqui lo tendremos que poner tambien en\nnuestra aplicación en algún momento, en el caso de Android, lo haremos en el\nmanifest.\n\nSiguiente:\n\nEncontrar el SDK\nBueno esto realmente depende de que queramos hacer y de como tengamos montado el\nentorno en Azure, en mi caso he creado un Mobile AppService, por lo que en\ncondiciones normales deberíamos trabajar con el SDK para ello.\n\nBien pues en este caso deberia ser bastante fácil, la documentación oficial esta\nbastante bien para esto:\nAzure SDK Android\n[https://docs.microsoft.com/es-es/azure/app-service-mobile/app-service-mobile-android-how-to-use-client-library]\n\nComo veis al inicio te lo dice, básicamente usa el compile pertinente y un par\nde cosas más y listo.\n\nY por último:\n\nCódigo necesario para el login\nBien seguramente si habeis mirado los links que he puesto más arriba habréis\nvisto que casi todo el código que necesitamos ya estaba, concretamente en este \nAzure SDK Android\n[https://docs.microsoft.com/es-es/azure/app-service-mobile/app-service-mobile-android-how-to-use-client-library]\n\nCreamos una conexión de cliente en el onCreate:\n\nMobileServiceClient mClient = new MobileServiceClient(\n    \"<MobileAppUrl>\",       // Replace with the Site URL\n    this);                  // Your application Context\n\n\nPor si no lo tenéis claro MobileAppUrl es la url de vuestro APPService algo\nsimilar a:\n\nhttps://nombreDeApp.azurewebsites.net\n\n\nEl resto es como viene en la documentación, pero en nuestro caso como provider \nde login de backend ponemos aad o podemos usar:\n\nMobileServiceAuthenticationProvider.WindowsAzureActiveDirectory\n\n\nUn par de detalles muy importantes:\n\n * siempre que en la documentación pone algo de url_scheme se refiere a la url\n   de nuestra app o al menos al nombre.\n * Tenemos que tener esto en el manifest.xml (con la URL de nuestra app)\n\n<activity android:name=\"com.microsoft.windowsazure.mobileservices.authentication.RedirectUrlActivity\">\n    <intent-filter>\n        <action android:name=\"android.intent.action.VIEW\" />\n        <category android:name=\"android.intent.category.DEFAULT\" />\n        <category android:name=\"android.intent.category.BROWSABLE\" />\n        <data android:scheme=\"nombreDeApp\" android:host=\"easyauth.callback\"/>\n    </intent-filter>\n</activity>\n\n\nOJO con ese easyauth.callback es el que permitimos más arriba en las\nredirecciones y sin el nada funciona.\n\nComo tal solo he remarcado las partes que me han parecido más importantes, la\ngran mayoria de las cosas funcionan bien siguiendo la información que aparece en\nlos links que os he comentado más arriba.\n\nEn otro post comentare como obtener datos del usuario que ha realizado el login,\nya que a simple vista no es muy intuitivo, hasta la próximaaaaaa.","html":"<!--kg-card-begin: markdown--><p>Estreno otra sección, en este caso estará centrado en problemas que me he ido encontrado con los servicios <strong>Cloud</strong> a la hora de desarrollar alguna aplicación nativa para Android o IOS.<br>\nEn este caso le toca el turno a Azure, por ciertas necesidades he tenido que &quot;pegarme&quot; con el servicio para que me funcionara el Login con el servicio de Azure Active Directory.<br>\nVuelve a ser por el problema de la documentación existente, que creo que es el único problema con los servicios Cloud, que la documentación o no esta clara o no esta actualizada.</p>\n<p>Este escenario es muy simple, queremos hacer login, con una app Android, usando usuarios pertenecientes a Azure Active Directory, en un principio debería ser bastante fácil pero por lo menos en mi caso he tenido algún que otro problema.</p>\n<p>Primero de todo:</p>\n<h2 id=\"configurarelappserviceparaellogin\">Configurar el AppService para el login</h2>\n<p>Teóricamente bastante sencillo, vamos a la doc oficial:<br>\n<a href=\"https://docs.microsoft.com/es-es/azure/app-service-mobile/app-service-mobile-how-to-configure-active-directory-authentication\">Configure AAD in APPService</a></p>\n<p>Y la seguimos, como tal hacemos todo y pensamos que todo esta bien, pero a la hora de probarlo falta alguna cosilla, que os voy adelantando por aqui:</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Azure.png\" alt=\"\"></p>\n<p>Como véis en la foto en las redirecciones URL permitidas necesitamos añadirle algo similar a lo que veis en la foto, básicamente es el nombre de tu <strong>appservice</strong> seguido de un extra:</p>\n<pre><code>appservicename://easyauth.callback\n</code></pre>\n<p>Esto es importante, lo que pongamos aqui lo tendremos que poner tambien en nuestra aplicación en algún momento, en el caso de Android, lo haremos en el manifest.</p>\n<p>Siguiente:</p>\n<h2 id=\"encontrarelsdk\">Encontrar el SDK</h2>\n<p>Bueno esto realmente depende de que queramos hacer y de como tengamos montado el entorno en Azure, en mi caso he creado un Mobile AppService, por lo que en condiciones normales deberíamos trabajar con el SDK para ello.</p>\n<p>Bien pues en este caso deberia ser bastante fácil, la documentación oficial esta bastante bien para esto:<br>\n<a href=\"https://docs.microsoft.com/es-es/azure/app-service-mobile/app-service-mobile-android-how-to-use-client-library\">Azure SDK Android</a></p>\n<p>Como veis al inicio te lo dice, básicamente usa el compile pertinente y un par de cosas más y listo.</p>\n<p>Y por último:</p>\n<h2 id=\"cdigonecesarioparaellogin\">Código necesario para el login</h2>\n<p>Bien seguramente si habeis mirado los links que he puesto más arriba habréis visto que casi todo el código que necesitamos ya estaba, concretamente en este <a href=\"https://docs.microsoft.com/es-es/azure/app-service-mobile/app-service-mobile-android-how-to-use-client-library\">Azure SDK Android</a></p>\n<p>Creamos una conexión de cliente en el onCreate:</p>\n<pre><code>MobileServiceClient mClient = new MobileServiceClient(\n    &quot;&lt;MobileAppUrl&gt;&quot;,       // Replace with the Site URL\n    this);                  // Your application Context\n</code></pre>\n<p>Por si no lo tenéis claro <strong>MobileAppUrl</strong> es la url de vuestro APPService algo similar a:</p>\n<pre><code>https://nombreDeApp.azurewebsites.net\n</code></pre>\n<p>El resto es como viene en la documentación, pero en nuestro caso como <strong>provider</strong> de login de backend ponemos <strong>aad</strong> o podemos usar:</p>\n<pre><code>MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory\n</code></pre>\n<p><span style=\"color:red\">Un par de detalles muy importantes</span>:</p>\n<ul>\n<li>siempre que en la documentación pone algo de <strong>url_scheme</strong> se refiere a la url de nuestra app o al menos al nombre.</li>\n<li>Tenemos que tener esto en el <strong>manifest.xml</strong> (con la URL de nuestra app)</li>\n</ul>\n<pre><code>&lt;activity android:name=&quot;com.microsoft.windowsazure.mobileservices.authentication.RedirectUrlActivity&quot;&gt;\n    &lt;intent-filter&gt;\n        &lt;action android:name=&quot;android.intent.action.VIEW&quot; /&gt;\n        &lt;category android:name=&quot;android.intent.category.DEFAULT&quot; /&gt;\n        &lt;category android:name=&quot;android.intent.category.BROWSABLE&quot; /&gt;\n        &lt;data android:scheme=&quot;nombreDeApp&quot; android:host=&quot;easyauth.callback&quot;/&gt;\n    &lt;/intent-filter&gt;\n&lt;/activity&gt;\n</code></pre>\n<p><strong>OJO con ese easyauth.callback</strong> es el que permitimos más arriba en las redirecciones y sin el nada funciona.</p>\n<p>Como tal solo he remarcado las partes que me han parecido más importantes, la gran mayoria de las cosas funcionan bien siguiendo la información que aparece en los links que os he comentado más arriba.</p>\n<p>En otro post comentare como obtener datos del usuario que ha realizado el login, ya que a simple vista no es muy intuitivo, hasta la próximaaaaaa.</p>\n<!--kg-card-end: markdown-->","url":"https://jlgarcia.fulldev.ninja/cloud-adventures-android-y-azure-active-directory-login/","canonical_url":null,"uuid":"2cf0a3ce-fac7-446d-9762-6ce5740def4e","codeinjection_foot":null,"codeinjection_head":null,"codeinjection_styles":null,"comment_id":"31","reading_time":3,"send_email_when_published":false,"email_subject":null,"childHtmlRehype":{"html":"<!--kg-card-begin: markdown--><p>Estreno otra sección, en este caso estará centrado en problemas que me he ido encontrado con los servicios <strong>Cloud</strong> a la hora de desarrollar alguna aplicación nativa para Android o IOS.<br>\nEn este caso le toca el turno a Azure, por ciertas necesidades he tenido que \"pegarme\" con el servicio para que me funcionara el Login con el servicio de Azure Active Directory.<br>\nVuelve a ser por el problema de la documentación existente, que creo que es el único problema con los servicios Cloud, que la documentación o no esta clara o no esta actualizada.</p>\n<p>Este escenario es muy simple, queremos hacer login, con una app Android, usando usuarios pertenecientes a Azure Active Directory, en un principio debería ser bastante fácil pero por lo menos en mi caso he tenido algún que otro problema.</p>\n<p>Primero de todo:</p>\n<h2 id=\"configurarelappserviceparaellogin\">Configurar el AppService para el login</h2>\n<p>Teóricamente bastante sencillo, vamos a la doc oficial:<br>\n<a href=\"https://docs.microsoft.com/es-es/azure/app-service-mobile/app-service-mobile-how-to-configure-active-directory-authentication\">Configure AAD in APPService</a></p>\n<p>Y la seguimos, como tal hacemos todo y pensamos que todo esta bien, pero a la hora de probarlo falta alguna cosilla, que os voy adelantando por aqui:</p>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Azure.png\" alt=\"\"></p>\n<p>Como véis en la foto en las redirecciones URL permitidas necesitamos añadirle algo similar a lo que veis en la foto, básicamente es el nombre de tu <strong>appservice</strong> seguido de un extra:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">appservicename://easyauth.callback\n</code></pre></div>\n<p>Esto es importante, lo que pongamos aqui lo tendremos que poner tambien en nuestra aplicación en algún momento, en el caso de Android, lo haremos en el manifest.</p>\n<p>Siguiente:</p>\n<h2 id=\"encontrarelsdk\">Encontrar el SDK</h2>\n<p>Bueno esto realmente depende de que queramos hacer y de como tengamos montado el entorno en Azure, en mi caso he creado un Mobile AppService, por lo que en condiciones normales deberíamos trabajar con el SDK para ello.</p>\n<p>Bien pues en este caso deberia ser bastante fácil, la documentación oficial esta bastante bien para esto:<br>\n<a href=\"https://docs.microsoft.com/es-es/azure/app-service-mobile/app-service-mobile-android-how-to-use-client-library\">Azure SDK Android</a></p>\n<p>Como veis al inicio te lo dice, básicamente usa el compile pertinente y un par de cosas más y listo.</p>\n<p>Y por último:</p>\n<h2 id=\"cdigonecesarioparaellogin\">Código necesario para el login</h2>\n<p>Bien seguramente si habeis mirado los links que he puesto más arriba habréis visto que casi todo el código que necesitamos ya estaba, concretamente en este <a href=\"https://docs.microsoft.com/es-es/azure/app-service-mobile/app-service-mobile-android-how-to-use-client-library\">Azure SDK Android</a></p>\n<p>Creamos una conexión de cliente en el onCreate:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">MobileServiceClient mClient = new MobileServiceClient(\n    \"&#x3C;MobileAppUrl>\",       // Replace with the Site URL\n    this);                  // Your application Context\n</code></pre></div>\n<p>Por si no lo tenéis claro <strong>MobileAppUrl</strong> es la url de vuestro APPService algo similar a:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">https://nombreDeApp.azurewebsites.net\n</code></pre></div>\n<p>El resto es como viene en la documentación, pero en nuestro caso como <strong>provider</strong> de login de backend ponemos <strong>aad</strong> o podemos usar:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory\n</code></pre></div>\n<p><span style=\"color:red\">Un par de detalles muy importantes</span>:</p>\n<ul>\n<li>siempre que en la documentación pone algo de <strong>url_scheme</strong> se refiere a la url de nuestra app o al menos al nombre.</li>\n<li>Tenemos que tener esto en el <strong>manifest.xml</strong> (con la URL de nuestra app)</li>\n</ul>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">&#x3C;activity android:name=\"com.microsoft.windowsazure.mobileservices.authentication.RedirectUrlActivity\">\n    &#x3C;intent-filter>\n        &#x3C;action android:name=\"android.intent.action.VIEW\" />\n        &#x3C;category android:name=\"android.intent.category.DEFAULT\" />\n        &#x3C;category android:name=\"android.intent.category.BROWSABLE\" />\n        &#x3C;data android:scheme=\"nombreDeApp\" android:host=\"easyauth.callback\"/>\n    &#x3C;/intent-filter>\n&#x3C;/activity>\n</code></pre></div>\n<p><strong>OJO con ese easyauth.callback</strong> es el que permitimos más arriba en las redirecciones y sin el nada funciona.</p>\n<p>Como tal solo he remarcado las partes que me han parecido más importantes, la gran mayoria de las cosas funcionan bien siguiendo la información que aparece en los links que os he comentado más arriba.</p>\n<p>En otro post comentare como obtener datos del usuario que ha realizado el login, ya que a simple vista no es muy intuitivo, hasta la próximaaaaaa.</p>\n<!--kg-card-end: markdown-->","htmlAst":{"type":"root","children":[{"type":"comment","value":"kg-card-begin: markdown"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Estreno otra sección, en este caso estará centrado en problemas que me he ido encontrado con los servicios "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Cloud"}]},{"type":"text","value":" a la hora de desarrollar alguna aplicación nativa para Android o IOS."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nEn este caso le toca el turno a Azure, por ciertas necesidades he tenido que \"pegarme\" con el servicio para que me funcionara el Login con el servicio de Azure Active Directory."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nVuelve a ser por el problema de la documentación existente, que creo que es el único problema con los servicios Cloud, que la documentación o no esta clara o no esta actualizada."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Este escenario es muy simple, queremos hacer login, con una app Android, usando usuarios pertenecientes a Azure Active Directory, en un principio debería ser bastante fácil pero por lo menos en mi caso he tenido algún que otro problema."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Primero de todo:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"configurarelappserviceparaellogin"},"children":[{"type":"text","value":"Configurar el AppService para el login"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Teóricamente bastante sencillo, vamos a la doc oficial:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"a","properties":{"href":"https://docs.microsoft.com/es-es/azure/app-service-mobile/app-service-mobile-how-to-configure-active-directory-authentication"},"children":[{"type":"text","value":"Configure AAD in APPService"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Y la seguimos, como tal hacemos todo y pensamos que todo esta bien, pero a la hora de probarlo falta alguna cosilla, que os voy adelantando por aqui:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Azure.png","alt":""},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Como véis en la foto en las redirecciones URL permitidas necesitamos añadirle algo similar a lo que veis en la foto, básicamente es el nombre de tu "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"appservice"}]},{"type":"text","value":" seguido de un extra:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"appservicename://easyauth.callback\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Esto es importante, lo que pongamos aqui lo tendremos que poner tambien en nuestra aplicación en algún momento, en el caso de Android, lo haremos en el manifest."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Siguiente:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"encontrarelsdk"},"children":[{"type":"text","value":"Encontrar el SDK"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Bueno esto realmente depende de que queramos hacer y de como tengamos montado el entorno en Azure, en mi caso he creado un Mobile AppService, por lo que en condiciones normales deberíamos trabajar con el SDK para ello."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Bien pues en este caso deberia ser bastante fácil, la documentación oficial esta bastante bien para esto:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"a","properties":{"href":"https://docs.microsoft.com/es-es/azure/app-service-mobile/app-service-mobile-android-how-to-use-client-library"},"children":[{"type":"text","value":"Azure SDK Android"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Como veis al inicio te lo dice, básicamente usa el compile pertinente y un par de cosas más y listo."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Y por último:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"cdigonecesarioparaellogin"},"children":[{"type":"text","value":"Código necesario para el login"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Bien seguramente si habeis mirado los links que he puesto más arriba habréis visto que casi todo el código que necesitamos ya estaba, concretamente en este "},{"type":"element","tagName":"a","properties":{"href":"https://docs.microsoft.com/es-es/azure/app-service-mobile/app-service-mobile-android-how-to-use-client-library"},"children":[{"type":"text","value":"Azure SDK Android"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Creamos una conexión de cliente en el onCreate:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"MobileServiceClient mClient = new MobileServiceClient(\n    \"<MobileAppUrl>\",       // Replace with the Site URL\n    this);                  // Your application Context\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Por si no lo tenéis claro "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"MobileAppUrl"}]},{"type":"text","value":" es la url de vuestro APPService algo similar a:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"https://nombreDeApp.azurewebsites.net\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"El resto es como viene en la documentación, pero en nuestro caso como "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"provider"}]},{"type":"text","value":" de login de backend ponemos "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"aad"}]},{"type":"text","value":" o podemos usar:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"span","properties":{"style":"color:red"},"children":[{"type":"text","value":"Un par de detalles muy importantes"}]},{"type":"text","value":":"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"siempre que en la documentación pone algo de "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"url_scheme"}]},{"type":"text","value":" se refiere a la url de nuestra app o al menos al nombre."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Tenemos que tener esto en el "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"manifest.xml"}]},{"type":"text","value":" (con la URL de nuestra app)"}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"<activity android:name=\"com.microsoft.windowsazure.mobileservices.authentication.RedirectUrlActivity\">\n    <intent-filter>\n        <action android:name=\"android.intent.action.VIEW\" />\n        <category android:name=\"android.intent.category.DEFAULT\" />\n        <category android:name=\"android.intent.category.BROWSABLE\" />\n        <data android:scheme=\"nombreDeApp\" android:host=\"easyauth.callback\"/>\n    </intent-filter>\n</activity>\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"OJO con ese easyauth.callback"}]},{"type":"text","value":" es el que permitimos más arriba en las redirecciones y sin el nada funciona."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Como tal solo he remarcado las partes que me han parecido más importantes, la gran mayoria de las cosas funcionan bien siguiendo la información que aparece en los links que os he comentado más arriba."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"En otro post comentare como obtener datos del usuario que ha realizado el login, ya que a simple vista no es muy intuitivo, hasta la próximaaaaaa."}]},{"type":"text","value":"\n"},{"type":"comment","value":"kg-card-end: markdown"}],"data":{"quirksMode":false}},"tableOfContents":[{"id":"configurarelappserviceparaellogin","heading":"Configurar el AppService para el login"},{"id":"encontrarelsdk","heading":"Encontrar el SDK"},{"id":"cdigonecesarioparaellogin","heading":"Código necesario para el login"}]},"featureImageSharp":{"base":"cloud-ninjaaz.png","publicURL":"/static/258a34bdac22a1c7f123fe43c9931f62/cloud-ninjaaz.png","imageMeta":{"width":777,"height":471},"childImageSharp":{"fluid":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAADG0lEQVQoz3WT709bdRTG79+xmJnoiy3ZBoPS3l7ae29v6XBBoKQd2yAbE6TCBpXCghQWMIE5u4RCA52oiMYyfAFEfiglFJK98U0zYZOElUWgCSiS6HzFCwmBj7eX+dKTnHxzck6e5znnfI/gUB04FEV3FYcscxLLr105iR0OFFWj6JKD0K1sytxuKm/5KCxyY7WpaJqGatRpCKrmQil8F7nIi91dieq8hFx6Hbm4HLnkGqrDiaYD2lQXtSUm4iEPr7ZW4J9d/txIEvBVkJ9vx+l0GqCCrINItZ3Yy2vJv9mCfKUaa8NDrLfvY6tqQVMVCpwakk2hyCXze8zLb4Mmfg1nsxvNIf11GQWqHbusK80otL7jQXJXIXp92IqvYSmtwnL5KmLJDcSy95BkF5JdM1qenZkmY+3N9ZjPv82dmkoODw8Ze/wYm10+abmuTORhVRbB6yZdgUJvdTaf3LxI4EoeLVctDDfkEvSepbu72wA7Pj7mr1d/s7CQYPePPf6zYDCIxSIifHH7IqEaMzF/FhFfDhPN5/n+7mtvOceTe+cYb3yL7vYm/s+Ojo6oq6tHkvIRSgvtfOjJ5Y5HpMEr0lRu4UaxxPtuK/UeK3XuPHxuizHDjo4OhoaGiEQi9PX10d8fYWBgEJ/vA0TRqm/bifDt6Bg/JZ9hlhTiiScEWu/x6PMRPvvyG5rutvNycxvX5VIDaHR0lNOn36Srq4u5uTkuXMjC5XLx/PkvtLW1YTZbEBYTCUN2dHCAl+vrhHt7mZ+Ps5hY4H5Pj5H78YdZZmZmWV5e5syZs8RiMfb29sjJySUcDhs1icSioVJI6ICpVIp0Os3BwYHO/jHT09O6zxAKhdjZ2WFtbY39/X3i8XlOnXpDb7efzc1NQ9Hq6qq+oAW2t7epqKhEWFl5xvj4ONHoI4Ops7OLDEmmKBqN8uJFikCg2cgtLS3h9/vZ2Njg6dOfjUVkLJVaN96xse8QRkZG6NXbVPTTSyaTNDb6jaFnBt7a+hGTk5OYTHmG4gzB8PBXbG2lqa6u0b9SDxMTE/qVFPDgwadMTU3xL8OMWyEgcl/LAAAAAElFTkSuQmCC","aspectRatio":1.650943396226415,"src":"/static/258a34bdac22a1c7f123fe43c9931f62/60290/cloud-ninjaaz.png","srcSet":"/static/258a34bdac22a1c7f123fe43c9931f62/847ef/cloud-ninjaaz.png 175w,\n/static/258a34bdac22a1c7f123fe43c9931f62/91cba/cloud-ninjaaz.png 350w,\n/static/258a34bdac22a1c7f123fe43c9931f62/60290/cloud-ninjaaz.png 700w,\n/static/258a34bdac22a1c7f123fe43c9931f62/d1e92/cloud-ninjaaz.png 777w","srcWebp":"/static/258a34bdac22a1c7f123fe43c9931f62/89afa/cloud-ninjaaz.webp","srcSetWebp":"/static/258a34bdac22a1c7f123fe43c9931f62/9fca7/cloud-ninjaaz.webp 175w,\n/static/258a34bdac22a1c7f123fe43c9931f62/37a4e/cloud-ninjaaz.webp 350w,\n/static/258a34bdac22a1c7f123fe43c9931f62/89afa/cloud-ninjaaz.webp 700w,\n/static/258a34bdac22a1c7f123fe43c9931f62/60436/cloud-ninjaaz.webp 777w","sizes":"(max-width: 700px) 100vw, 700px"}}}},"allGhostPost":{"edges":[{"node":{"id":"Ghost__Post__5a338158333e0f134c248f12","title":"Go Go Power Ra....ah que no: Go Parte 4 - Arrays y Slices II","slug":"go-parte-4-arrays-y-slices-ii","featured":false,"feature_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Untitled-3.png","excerpt":"En este post vamos a ir viendo como se podrian hacer las cosas mas habituales\ncon los Arrays o Slices, como puede ser recorrerlos, veremos tambien como\npodemos pasar de uno a otro para la optimización, sin mucho mas empezamos.\n\nRecorrer un array o slice\nEmpecemos por el caso más habitual y es la necesidad de recorrer el contenido de\nun array, en este punto voy a adelantar alguna otra cosa que no es solo de Array\no Slices, pero creo que es mejor verlo en esta parte.\n\nPara recorrer un array, tipic","custom_excerpt":null,"visibility":"public","created_at_pretty":"12 Jul 2017","published_at_pretty":"18 Jul 2017","updated_at_pretty":"11 Oct 2017","created_at":"2017-07-12T08:39:33.000+02:00","published_at":"2017-07-18T21:19:48.000+02:00","updated_at":"2017-10-11T13:46:06.000+02:00","meta_title":null,"meta_description":null,"og_description":null,"og_image":null,"og_title":null,"twitter_description":null,"twitter_image":null,"twitter_title":null,"authors":[{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":null}],"primary_author":{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":{"base":"Perfil.jpg","publicURL":"/static/b0de6281fb28a266510b3b09b9243e5a/Perfil.jpg","imageMeta":{"width":307,"height":307},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAUDBAb/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAGzw6zC6zHn+cLYP//EAB0QAAICAQUAAAAAAAAAAAAAAAEDAAIEEyEiIzL/2gAIAQEAAQUCifca8KgcKWVfUpkHsG5pxX//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/AR//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/AR//xAAdEAACAgEFAAAAAAAAAAAAAAAAARARcQISIUFR/9oACAEBAAY/AhU88xkb7N06a8P/xAAcEAEAAwEAAwEAAAAAAAAAAAABABEhMUFRYXH/2gAIAQEAAT8hR2pq40aqb+xIAeXibhW9JXr8joF4TBcSNe0//9oADAMBAAIAAwAAABDzDwD/xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/EB//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/EB//xAAcEAEAAgIDAQAAAAAAAAAAAAABABEhUTFhcfD/2gAIAQEAAT8QyItrELaTlatLwU63MvEW6vUNdy4LZQDn7iVApV9VLtANdWwKkuYq4Er1VZ//2Q==","aspectRatio":1,"src":"/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg","srcSet":"/static/b0de6281fb28a266510b3b09b9243e5a/f340b/Perfil.jpg 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/22d64/Perfil.jpg 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/aa249/Perfil.jpg 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/0dc33/Perfil.jpg 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/60667/Perfil.jpg 307w","srcWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp","srcSetWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/59cda/Perfil.webp 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/7da75/Perfil.webp 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f282e/Perfil.webp 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/a7b21/Perfil.webp 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f59af/Perfil.webp 307w","sizes":"(max-width: 110px) 100vw, 110px"}}}},"primary_tag":{"slug":"go","url":"https://jlgarcia.fulldev.ninja/tag/go/","name":"Go","visibility":"public","feature_image":null,"description":null,"meta_title":"Golang Ninjas","meta_description":"Aprenderemos a usar el nuevo lenguaje de Google para backend desde lo más básico a temas avanzados como concurrencia o api rest.","featureImageSharp":null},"tags":[{"slug":"go","url":"https://jlgarcia.fulldev.ninja/tag/go/","name":"Go","visibility":"public","feature_image":null,"description":null,"meta_title":"Golang Ninjas","meta_description":"Aprenderemos a usar el nuevo lenguaje de Google para backend desde lo más básico a temas avanzados como concurrencia o api rest.","featureImageSharp":null},{"slug":"golang","url":"https://jlgarcia.fulldev.ninja/tag/golang/","name":"Golang","visibility":"public","feature_image":null,"description":null,"meta_title":"Golang Ninjas","meta_description":"Aprenderemos a usar el nuevo lenguaje de Google para backend desde lo más básico a temas avanzados como concurrencia o api rest.","featureImageSharp":null}],"plaintext":"En este post vamos a ir viendo como se podrian hacer las cosas mas habituales\ncon los Arrays o Slices, como puede ser recorrerlos, veremos tambien como\npodemos pasar de uno a otro para la optimización, sin mucho mas empezamos.\n\nRecorrer un array o slice\nEmpecemos por el caso más habitual y es la necesidad de recorrer el contenido de\nun array, en este punto voy a adelantar alguna otra cosa que no es solo de Array\no Slices, pero creo que es mejor verlo en esta parte.\n\nPara recorrer un array, tipicamente lo hacemos un bucle for, pues en este caso\nGo tiene un proceso muy similar específico (aunque se podria simular un for\nnormal, haciendo el código a mano pero me parece innecesario, con el código lo\nvereis mejor)\n\nrangers := []string{\"Ranger Rosa\", \"Ranger Amarillo\"}\n\nfor index, ranger := range rangers {\n\tfmt.Println(\"El indice o posicion es: \", index)\n\tfmt.Println(\"El Ranger de esa posicion es:\", ranger)\n}\n\n\nCon un resultado similar a este:\n\nComo vemos aqui tenemos un par de palabras reservadas que no habiamos usado: for \ny range, mas o menos os podéis imaginar la funcion que tiene cada una,\nbásicamente esto quiere decir \"Por cada índice y ranger dentro del rango de\nrangers.....\"\n\nBastante sencillo no?? Si os fijais tenemos la declaración corta de variables :=\n, lo que esta haciendo es asignar en cada vuelta, el índice y el valor en los\nnombres de variables que hemos puesto(podrian ser otros perfectamente).\n\nY si no queremos el índice?? Básicamente ignoramos el resultado:\n\nfor _, ranger := range rangers {\n\tfmt.Println(\"El Ranger de esa posicion es:\", ranger)\n}\n\n\nEl _ en Go es un valor especial(funciona igual que en Swift por ejemplo) con el\nque estamos indicando que ignore ese resultado que podemos obtener de una\nfunción o cualquier otro proceso como puede ser este que acabamos de ver de\nrecorrer un array.\n\nSeparando un array\nO mas bien crear un subarray con parte del array original, es decir, veamos como\npartir un array para extrar el rango de posiciones que nos interese.\nEn go tenemos la posibilidad de seleccionar un rango de X posiciones dentro de\nun array, de una manera bastante sencilla:\n\nminiRangers := rangers[:2]\nfmt.Println(\"Hemos seleccionado del inicio a la posicion 2 sin incluirla:\")\nfmt.Println(miniRangers)\n\nminiRangers2 := rangers[2:4]\nfmt.Println(\"Hemos seleccionado desde la posicion 2 hasta la 4 sin incluirla:\")\nfmt.Println(miniRangers2)\n\nminiRangers3 := rangers[4:]\nfmt.Println(\"Hemos seleccionado desde la 4 hasta el final\")\nfmt.Println(miniRangers3)\n\n\n\n\nTambien es posible asignar al mismo array o resumiendo cortar el array:\n\nrangers := []string{\"Ranger Rosa\", \"Ranger Amarillo\", \"Ranger Rojo\", \"Ranger Verde\", \"Ranger Negro\"}\n\nrangers = rangers[2:4]\nfmt.Println(\"Hemos seleccionado del inicio a la posicion 2 sin incluirla:\")\nfmt.Println(rangers)\n\n\n\n\nTamaño y Capacidad\nEstos ya los hemos visto:\n\nfmt.Println(len(rangers))//Para el tamaño\n\nfmt.Println(len(rangers))//Capacidad\n\n\nAñadir\nTambien hemos visto como añadir, ya sea en un array hasta su tamaño designado y\nen un slice cuando no esta inicializado:\n\nvar rangersDesignados [2]string\nrangersDesignados = append(rangersDesignados,\"R.Rojo\",\"R.Verde\")\n\nrangersSlices = make([]string,2,10)\nappend(rangersSlices,\"R.Rojo\",\"R.Verde\")\n\n\nEliminar\nSiento decir que aqui el lenguaje nos falla un poco, ya que no ofrece ningun\nmétodo ya preparado para esto, como tal ya tenemos que jugar nosotros. En esta\npágina:SliceTricks [https://github.com/golang/go/wiki/SliceTricks]\nTenemos alguna forma de hacer las operaciones mas comunes de eliminar, cortar,\netc de manera eficiente.\n\nCopiar(Importante)\nEn un principio esto puede no parecer nada, estamos hablando de copiar un array\no slice en otro......bueno pues no es tan simple, ¿recordáis lo que comentamos\nen el post anterior sobre tamaño y capacidad? Por refrescar rápidamente, el \ntamaño era la cantidad de elementos que tenia un slice o array y la capacidad la\nreserva de elementos que puede contener, es decir, la cantidad máxima de\nelementos que puede tener. Recordemos que Go lo que hace es reservar un espacio\nen memoria para almacenar una cantidad aproximada de datos, lo importante venia\na la hora de aumentar, como tal el slice comentamos que al aumentar lo que hacia\nera reservarse el doble de la capacidad que tenia anteriormente. Esto con slices\npequeños esta muy bien, pero ¿y si tenemos un slice de 1000 elementos? En cuanto\nañadamos 1 más se reservara un espacio de 2000.\n\nPues bien con este escenario tenemos la accion de copiar como solución, lo que\nhacemos es copiar un array en otro con la capacidad ajustada a lo que queramos,\nla forma de usarlo es simple:\n\ncopy(destino, origen)\n\n\nBastante simple no? Pues veamos un ejemplo y apliquemos un poco de lógica para\noptimizar el consumo:\n\n//Creamos dos slices\nslice := []int{1, 2, 3, 4}\ncopia := make([]int, 4)\n\ncopy(copia, slice)\n\nfmt.Println(slice)\nfmt.Println(copia)\n\n\nComo vemos hemos creado un slice con la forma corta, con contenido, y otro vacio\ncon un tamaño y capacidad de 4. Si imprimimos el contenido todo estaría normal,\npero un detalle a tener en cuenta es que realmente copy tiene en cuenta la\ncapacidad del slice de destino (en este caso copia), como le hemos puesto una\ncapacidad de 4, nos copia todo el contenido. Pongamos un ejemplo si ponemos\nmenos:\n\n//Si cambiaramos copia con otra longitud\ncopia2 := make([]int, 2)\ncopy(copia2, slice)\nfmt.Println(slice)\nfmt.Println(copia2)\n//Veriamos como solo nos copia 2 elementos, \n\n\nLo mejor es controlar el tamaño(no la capacidad ojo), del slice origen y usar\neso para crear el destino:\n\n//para no equivocarnos lo ideal seria\ncopia3 := make([]int, len(slice))\ncopy(copia3, slice)\n\nfmt.Println(slice)\nfmt.Println(copia3)\n//Con esto si cambia el tamaño del slice la copia tambien.\n\n//Como buena practica, aunque segun el entorno, es añadir el doble del tamaño a la capacidad\ncopia4 := make([]int, len(slice), len(slice)*2) //O con la capacidad segun el caso\n    \ncopy(copia4, slice)\nfmt.Println(slice)\nfmt.Println(copia4)\n\n\nBueno creo que por el momento vamos a dejar los arrays y slices para continuar\ncon otras cosas, recordar mirar el link SliceTricks\n[https://github.com/golang/go/wiki/SliceTricks] y en otro de mis post tengo algo\nmas de trabajo con arrays: Go Tricks I\n[https://jlgarcia.fulldev.ninja/go-tricks-i-array-contains/]","html":"<!--kg-card-begin: markdown--><p>En este post vamos a ir viendo como se podrian hacer las cosas mas habituales con los Arrays o Slices, como puede ser recorrerlos, veremos tambien como podemos pasar de uno a otro para la optimización, sin mucho mas empezamos.</p>\n<h2 id=\"recorrerunarrayoslice\">Recorrer un array o slice</h2>\n<p>Empecemos por el caso más habitual y es la necesidad de recorrer el contenido de un array, en este punto voy a adelantar alguna otra cosa que no es solo de Array o Slices, pero creo que es mejor verlo en esta parte.</p>\n<p>Para recorrer un array, tipicamente lo hacemos un bucle <strong>for</strong>, pues en este caso Go tiene un proceso muy similar específico (aunque se podria simular un for normal, haciendo el código a mano pero me parece innecesario, con el código lo vereis mejor)</p>\n<pre><code>rangers := []string{&quot;Ranger Rosa&quot;, &quot;Ranger Amarillo&quot;}\n\nfor index, ranger := range rangers {\n\tfmt.Println(&quot;El indice o posicion es: &quot;, index)\n\tfmt.Println(&quot;El Ranger de esa posicion es:&quot;, ranger)\n}\n</code></pre>\n<p>Con un resultado similar a este:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen08.49.53.png\" alt=\"\"><br>\nComo vemos aqui tenemos un par de palabras reservadas que no habiamos usado: <strong>for</strong> y  <strong>range</strong>, mas o menos os podéis imaginar la funcion que tiene cada una, básicamente esto quiere decir &quot;Por cada índice y ranger dentro del rango de rangers.....&quot;</p>\n<p>Bastante sencillo no?? Si os fijais tenemos la declaración corta de variables <strong>:=</strong>, lo que esta haciendo es asignar en cada vuelta, el índice y el valor en los nombres de variables que hemos puesto(podrian ser otros perfectamente).</p>\n<p>Y si no queremos el índice?? Básicamente ignoramos el resultado:</p>\n<pre><code>for _, ranger := range rangers {\n\tfmt.Println(&quot;El Ranger de esa posicion es:&quot;, ranger)\n}\n</code></pre>\n<p>El <strong>_</strong> en Go es un valor especial(funciona igual que en Swift por ejemplo) con el que estamos indicando que ignore ese resultado que podemos obtener de una función o cualquier otro proceso como puede ser este que acabamos de ver de recorrer un array.</p>\n<h2 id=\"separandounarray\">Separando un array</h2>\n<p>O mas bien crear un subarray con parte del array original, es decir, veamos como partir un array para extrar el rango de posiciones que nos interese.<br>\nEn go tenemos la posibilidad de seleccionar un rango de X posiciones dentro de un array, de una manera bastante sencilla:</p>\n<pre><code>miniRangers := rangers[:2]\nfmt.Println(&quot;Hemos seleccionado del inicio a la posicion 2 sin incluirla:&quot;)\nfmt.Println(miniRangers)\n\nminiRangers2 := rangers[2:4]\nfmt.Println(&quot;Hemos seleccionado desde la posicion 2 hasta la 4 sin incluirla:&quot;)\nfmt.Println(miniRangers2)\n\nminiRangers3 := rangers[4:]\nfmt.Println(&quot;Hemos seleccionado desde la 4 hasta el final&quot;)\nfmt.Println(miniRangers3)\n</code></pre>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen09.09.05.png\" alt=\"\"></p>\n<p>Tambien es posible asignar al mismo array o resumiendo cortar el array:</p>\n<pre><code>rangers := []string{&quot;Ranger Rosa&quot;, &quot;Ranger Amarillo&quot;, &quot;Ranger Rojo&quot;, &quot;Ranger Verde&quot;, &quot;Ranger Negro&quot;}\n\nrangers = rangers[2:4]\nfmt.Println(&quot;Hemos seleccionado del inicio a la posicion 2 sin incluirla:&quot;)\nfmt.Println(rangers)\n</code></pre>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen09.12.15.png\" alt=\"\"></p>\n<h2 id=\"tamaoycapacidad\">Tamaño y Capacidad</h2>\n<p>Estos ya los hemos visto:</p>\n<pre><code>fmt.Println(len(rangers))//Para el tamaño\n\nfmt.Println(len(rangers))//Capacidad\n</code></pre>\n<h2 id=\"aadir\">Añadir</h2>\n<p>Tambien hemos visto como añadir, ya sea en un <strong>array</strong> hasta su tamaño designado y en un <strong>slice</strong> cuando no esta inicializado:</p>\n<pre><code>var rangersDesignados [2]string\nrangersDesignados = append(rangersDesignados,&quot;R.Rojo&quot;,&quot;R.Verde&quot;)\n\nrangersSlices = make([]string,2,10)\nappend(rangersSlices,&quot;R.Rojo&quot;,&quot;R.Verde&quot;)\n</code></pre>\n<h2 id=\"eliminar\">Eliminar</h2>\n<p>Siento decir que aqui el lenguaje nos falla un poco, ya que no ofrece ningun método ya preparado para esto, como tal ya tenemos que jugar nosotros. En esta página:<a href=\"https://github.com/golang/go/wiki/SliceTricks\">SliceTricks</a><br>\nTenemos alguna forma de hacer las operaciones mas comunes de eliminar, cortar, etc de manera eficiente.</p>\n<h2 id=\"copiarspanstylecolorredimportantespan\">Copiar<span style=\"color:red\">(Importante)</span></h2>\n<p>En un principio esto puede no parecer nada, estamos hablando de copiar un array o slice en otro......bueno pues no es tan simple, ¿recordáis lo que comentamos en el post anterior sobre tamaño y capacidad? Por refrescar rápidamente, el <strong>tamaño</strong> era la cantidad de elementos que tenia un slice o array y la <strong>capacidad</strong> la reserva de elementos que puede contener, es decir, la cantidad máxima de elementos que puede tener. Recordemos que Go lo que hace es reservar un espacio en memoria para almacenar una cantidad aproximada de datos, lo <span style=\"color:red\">importante</span> venia a la hora de aumentar, como tal el <strong>slice</strong> comentamos que al aumentar lo que hacia era reservarse el doble de la capacidad que tenia anteriormente. Esto con slices pequeños esta muy bien, pero ¿y si tenemos un slice de 1000 elementos? En cuanto añadamos 1 más se reservara un espacio de 2000.</p>\n<p>Pues bien con este escenario tenemos la accion de <span style=\"color:red\">copiar</span> como solución, lo que hacemos es copiar un array en otro con la capacidad ajustada a lo que queramos, la forma de usarlo es simple:</p>\n<pre><code>copy(destino, origen)\n</code></pre>\n<p>Bastante simple no? Pues veamos un ejemplo y apliquemos un poco de lógica para optimizar el consumo:</p>\n<pre><code>//Creamos dos slices\nslice := []int{1, 2, 3, 4}\ncopia := make([]int, 4)\n\ncopy(copia, slice)\n\nfmt.Println(slice)\nfmt.Println(copia)\n</code></pre>\n<p>Como vemos hemos creado un slice con la forma corta, con contenido, y otro vacio con un tamaño y capacidad de 4. Si imprimimos el contenido todo estaría normal, pero un detalle a tener en cuenta es que realmente <strong>copy</strong> tiene en cuenta la capacidad del slice de destino (en este caso copia), como le hemos puesto una capacidad de 4, nos copia todo el contenido. Pongamos un ejemplo si ponemos menos:</p>\n<pre><code>//Si cambiaramos copia con otra longitud\ncopia2 := make([]int, 2)\ncopy(copia2, slice)\nfmt.Println(slice)\nfmt.Println(copia2)\n//Veriamos como solo nos copia 2 elementos, \n</code></pre>\n<p>Lo mejor es controlar el tamaño(no la capacidad ojo), del slice origen y usar eso para crear el destino:</p>\n<pre><code>//para no equivocarnos lo ideal seria\ncopia3 := make([]int, len(slice))\ncopy(copia3, slice)\n\nfmt.Println(slice)\nfmt.Println(copia3)\n//Con esto si cambia el tamaño del slice la copia tambien.\n\n//Como buena practica, aunque segun el entorno, es añadir el doble del tamaño a la capacidad\ncopia4 := make([]int, len(slice), len(slice)*2) //O con la capacidad segun el caso\n    \ncopy(copia4, slice)\nfmt.Println(slice)\nfmt.Println(copia4)\n</code></pre>\n<p>Bueno creo que por el momento vamos a dejar los <strong>arrays</strong> y <strong>slices</strong> para continuar con otras cosas, recordar mirar el link <a href=\"https://github.com/golang/go/wiki/SliceTricks\">SliceTricks</a> y en otro de mis post tengo algo mas de trabajo con arrays: <a href=\"https://jlgarcia.fulldev.ninja/go-tricks-i-array-contains/\">Go Tricks I</a></p>\n<!--kg-card-end: markdown-->","url":"https://jlgarcia.fulldev.ninja/go-parte-4-arrays-y-slices-ii/","canonical_url":null,"uuid":"fcff7b39-793f-48db-b59d-161f6b0ea711","codeinjection_foot":null,"codeinjection_head":null,"codeinjection_styles":null,"comment_id":"30","reading_time":5,"send_email_when_published":false,"email_subject":null,"childHtmlRehype":{"html":"<!--kg-card-begin: markdown--><p>En este post vamos a ir viendo como se podrian hacer las cosas mas habituales con los Arrays o Slices, como puede ser recorrerlos, veremos tambien como podemos pasar de uno a otro para la optimización, sin mucho mas empezamos.</p>\n<h2 id=\"recorrerunarrayoslice\">Recorrer un array o slice</h2>\n<p>Empecemos por el caso más habitual y es la necesidad de recorrer el contenido de un array, en este punto voy a adelantar alguna otra cosa que no es solo de Array o Slices, pero creo que es mejor verlo en esta parte.</p>\n<p>Para recorrer un array, tipicamente lo hacemos un bucle <strong>for</strong>, pues en este caso Go tiene un proceso muy similar específico (aunque se podria simular un for normal, haciendo el código a mano pero me parece innecesario, con el código lo vereis mejor)</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">rangers := []string{\"Ranger Rosa\", \"Ranger Amarillo\"}\n\nfor index, ranger := range rangers {\n\tfmt.Println(\"El indice o posicion es: \", index)\n\tfmt.Println(\"El Ranger de esa posicion es:\", ranger)\n}\n</code></pre></div>\n<p>Con un resultado similar a este:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen08.49.53.png\" alt=\"\"><br>\nComo vemos aqui tenemos un par de palabras reservadas que no habiamos usado: <strong>for</strong> y  <strong>range</strong>, mas o menos os podéis imaginar la funcion que tiene cada una, básicamente esto quiere decir \"Por cada índice y ranger dentro del rango de rangers.....\"</p>\n<p>Bastante sencillo no?? Si os fijais tenemos la declaración corta de variables <strong>:=</strong>, lo que esta haciendo es asignar en cada vuelta, el índice y el valor en los nombres de variables que hemos puesto(podrian ser otros perfectamente).</p>\n<p>Y si no queremos el índice?? Básicamente ignoramos el resultado:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">for _, ranger := range rangers {\n\tfmt.Println(\"El Ranger de esa posicion es:\", ranger)\n}\n</code></pre></div>\n<p>El <strong>_</strong> en Go es un valor especial(funciona igual que en Swift por ejemplo) con el que estamos indicando que ignore ese resultado que podemos obtener de una función o cualquier otro proceso como puede ser este que acabamos de ver de recorrer un array.</p>\n<h2 id=\"separandounarray\">Separando un array</h2>\n<p>O mas bien crear un subarray con parte del array original, es decir, veamos como partir un array para extrar el rango de posiciones que nos interese.<br>\nEn go tenemos la posibilidad de seleccionar un rango de X posiciones dentro de un array, de una manera bastante sencilla:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">miniRangers := rangers[:2]\nfmt.Println(\"Hemos seleccionado del inicio a la posicion 2 sin incluirla:\")\nfmt.Println(miniRangers)\n\nminiRangers2 := rangers[2:4]\nfmt.Println(\"Hemos seleccionado desde la posicion 2 hasta la 4 sin incluirla:\")\nfmt.Println(miniRangers2)\n\nminiRangers3 := rangers[4:]\nfmt.Println(\"Hemos seleccionado desde la 4 hasta el final\")\nfmt.Println(miniRangers3)\n</code></pre></div>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen09.09.05.png\" alt=\"\"></p>\n<p>Tambien es posible asignar al mismo array o resumiendo cortar el array:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">rangers := []string{\"Ranger Rosa\", \"Ranger Amarillo\", \"Ranger Rojo\", \"Ranger Verde\", \"Ranger Negro\"}\n\nrangers = rangers[2:4]\nfmt.Println(\"Hemos seleccionado del inicio a la posicion 2 sin incluirla:\")\nfmt.Println(rangers)\n</code></pre></div>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen09.12.15.png\" alt=\"\"></p>\n<h2 id=\"tamaoycapacidad\">Tamaño y Capacidad</h2>\n<p>Estos ya los hemos visto:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">fmt.Println(len(rangers))//Para el tamaño\n\nfmt.Println(len(rangers))//Capacidad\n</code></pre></div>\n<h2 id=\"aadir\">Añadir</h2>\n<p>Tambien hemos visto como añadir, ya sea en un <strong>array</strong> hasta su tamaño designado y en un <strong>slice</strong> cuando no esta inicializado:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">var rangersDesignados [2]string\nrangersDesignados = append(rangersDesignados,\"R.Rojo\",\"R.Verde\")\n\nrangersSlices = make([]string,2,10)\nappend(rangersSlices,\"R.Rojo\",\"R.Verde\")\n</code></pre></div>\n<h2 id=\"eliminar\">Eliminar</h2>\n<p>Siento decir que aqui el lenguaje nos falla un poco, ya que no ofrece ningun método ya preparado para esto, como tal ya tenemos que jugar nosotros. En esta página:<a href=\"https://github.com/golang/go/wiki/SliceTricks\">SliceTricks</a><br>\nTenemos alguna forma de hacer las operaciones mas comunes de eliminar, cortar, etc de manera eficiente.</p>\n<h2 id=\"copiarspanstylecolorredimportantespan\">Copiar<span style=\"color:red\">(Importante)</span></h2>\n<p>En un principio esto puede no parecer nada, estamos hablando de copiar un array o slice en otro......bueno pues no es tan simple, ¿recordáis lo que comentamos en el post anterior sobre tamaño y capacidad? Por refrescar rápidamente, el <strong>tamaño</strong> era la cantidad de elementos que tenia un slice o array y la <strong>capacidad</strong> la reserva de elementos que puede contener, es decir, la cantidad máxima de elementos que puede tener. Recordemos que Go lo que hace es reservar un espacio en memoria para almacenar una cantidad aproximada de datos, lo <span style=\"color:red\">importante</span> venia a la hora de aumentar, como tal el <strong>slice</strong> comentamos que al aumentar lo que hacia era reservarse el doble de la capacidad que tenia anteriormente. Esto con slices pequeños esta muy bien, pero ¿y si tenemos un slice de 1000 elementos? En cuanto añadamos 1 más se reservara un espacio de 2000.</p>\n<p>Pues bien con este escenario tenemos la accion de <span style=\"color:red\">copiar</span> como solución, lo que hacemos es copiar un array en otro con la capacidad ajustada a lo que queramos, la forma de usarlo es simple:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">copy(destino, origen)\n</code></pre></div>\n<p>Bastante simple no? Pues veamos un ejemplo y apliquemos un poco de lógica para optimizar el consumo:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">//Creamos dos slices\nslice := []int{1, 2, 3, 4}\ncopia := make([]int, 4)\n\ncopy(copia, slice)\n\nfmt.Println(slice)\nfmt.Println(copia)\n</code></pre></div>\n<p>Como vemos hemos creado un slice con la forma corta, con contenido, y otro vacio con un tamaño y capacidad de 4. Si imprimimos el contenido todo estaría normal, pero un detalle a tener en cuenta es que realmente <strong>copy</strong> tiene en cuenta la capacidad del slice de destino (en este caso copia), como le hemos puesto una capacidad de 4, nos copia todo el contenido. Pongamos un ejemplo si ponemos menos:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">//Si cambiaramos copia con otra longitud\ncopia2 := make([]int, 2)\ncopy(copia2, slice)\nfmt.Println(slice)\nfmt.Println(copia2)\n//Veriamos como solo nos copia 2 elementos, \n</code></pre></div>\n<p>Lo mejor es controlar el tamaño(no la capacidad ojo), del slice origen y usar eso para crear el destino:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">//para no equivocarnos lo ideal seria\ncopia3 := make([]int, len(slice))\ncopy(copia3, slice)\n\nfmt.Println(slice)\nfmt.Println(copia3)\n//Con esto si cambia el tamaño del slice la copia tambien.\n\n//Como buena practica, aunque segun el entorno, es añadir el doble del tamaño a la capacidad\ncopia4 := make([]int, len(slice), len(slice)*2) //O con la capacidad segun el caso\n    \ncopy(copia4, slice)\nfmt.Println(slice)\nfmt.Println(copia4)\n</code></pre></div>\n<p>Bueno creo que por el momento vamos a dejar los <strong>arrays</strong> y <strong>slices</strong> para continuar con otras cosas, recordar mirar el link <a href=\"https://github.com/golang/go/wiki/SliceTricks\">SliceTricks</a> y en otro de mis post tengo algo mas de trabajo con arrays: <a href=\"/go-tricks-i-array-contains/\">Go Tricks I</a></p>\n<!--kg-card-end: markdown-->","htmlAst":{"type":"root","children":[{"type":"comment","value":"kg-card-begin: markdown"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"En este post vamos a ir viendo como se podrian hacer las cosas mas habituales con los Arrays o Slices, como puede ser recorrerlos, veremos tambien como podemos pasar de uno a otro para la optimización, sin mucho mas empezamos."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"recorrerunarrayoslice"},"children":[{"type":"text","value":"Recorrer un array o slice"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Empecemos por el caso más habitual y es la necesidad de recorrer el contenido de un array, en este punto voy a adelantar alguna otra cosa que no es solo de Array o Slices, pero creo que es mejor verlo en esta parte."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Para recorrer un array, tipicamente lo hacemos un bucle "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"for"}]},{"type":"text","value":", pues en este caso Go tiene un proceso muy similar específico (aunque se podria simular un for normal, haciendo el código a mano pero me parece innecesario, con el código lo vereis mejor)"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"rangers := []string{\"Ranger Rosa\", \"Ranger Amarillo\"}\n\nfor index, ranger := range rangers {\n\tfmt.Println(\"El indice o posicion es: \", index)\n\tfmt.Println(\"El Ranger de esa posicion es:\", ranger)\n}\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Con un resultado similar a este:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen08.49.53.png","alt":""},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nComo vemos aqui tenemos un par de palabras reservadas que no habiamos usado: "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"for"}]},{"type":"text","value":" y  "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"range"}]},{"type":"text","value":", mas o menos os podéis imaginar la funcion que tiene cada una, básicamente esto quiere decir \"Por cada índice y ranger dentro del rango de rangers.....\""}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Bastante sencillo no?? Si os fijais tenemos la declaración corta de variables "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":":="}]},{"type":"text","value":", lo que esta haciendo es asignar en cada vuelta, el índice y el valor en los nombres de variables que hemos puesto(podrian ser otros perfectamente)."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Y si no queremos el índice?? Básicamente ignoramos el resultado:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"for _, ranger := range rangers {\n\tfmt.Println(\"El Ranger de esa posicion es:\", ranger)\n}\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"El "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"_"}]},{"type":"text","value":" en Go es un valor especial(funciona igual que en Swift por ejemplo) con el que estamos indicando que ignore ese resultado que podemos obtener de una función o cualquier otro proceso como puede ser este que acabamos de ver de recorrer un array."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"separandounarray"},"children":[{"type":"text","value":"Separando un array"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"O mas bien crear un subarray con parte del array original, es decir, veamos como partir un array para extrar el rango de posiciones que nos interese."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nEn go tenemos la posibilidad de seleccionar un rango de X posiciones dentro de un array, de una manera bastante sencilla:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"miniRangers := rangers[:2]\nfmt.Println(\"Hemos seleccionado del inicio a la posicion 2 sin incluirla:\")\nfmt.Println(miniRangers)\n\nminiRangers2 := rangers[2:4]\nfmt.Println(\"Hemos seleccionado desde la posicion 2 hasta la 4 sin incluirla:\")\nfmt.Println(miniRangers2)\n\nminiRangers3 := rangers[4:]\nfmt.Println(\"Hemos seleccionado desde la 4 hasta el final\")\nfmt.Println(miniRangers3)\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen09.09.05.png","alt":""},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Tambien es posible asignar al mismo array o resumiendo cortar el array:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"rangers := []string{\"Ranger Rosa\", \"Ranger Amarillo\", \"Ranger Rojo\", \"Ranger Verde\", \"Ranger Negro\"}\n\nrangers = rangers[2:4]\nfmt.Println(\"Hemos seleccionado del inicio a la posicion 2 sin incluirla:\")\nfmt.Println(rangers)\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen09.12.15.png","alt":""},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"tamaoycapacidad"},"children":[{"type":"text","value":"Tamaño y Capacidad"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Estos ya los hemos visto:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"fmt.Println(len(rangers))//Para el tamaño\n\nfmt.Println(len(rangers))//Capacidad\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"aadir"},"children":[{"type":"text","value":"Añadir"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Tambien hemos visto como añadir, ya sea en un "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"array"}]},{"type":"text","value":" hasta su tamaño designado y en un "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"slice"}]},{"type":"text","value":" cuando no esta inicializado:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"var rangersDesignados [2]string\nrangersDesignados = append(rangersDesignados,\"R.Rojo\",\"R.Verde\")\n\nrangersSlices = make([]string,2,10)\nappend(rangersSlices,\"R.Rojo\",\"R.Verde\")\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"eliminar"},"children":[{"type":"text","value":"Eliminar"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Siento decir que aqui el lenguaje nos falla un poco, ya que no ofrece ningun método ya preparado para esto, como tal ya tenemos que jugar nosotros. En esta página:"},{"type":"element","tagName":"a","properties":{"href":"https://github.com/golang/go/wiki/SliceTricks"},"children":[{"type":"text","value":"SliceTricks"}]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nTenemos alguna forma de hacer las operaciones mas comunes de eliminar, cortar, etc de manera eficiente."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"copiarspanstylecolorredimportantespan"},"children":[{"type":"text","value":"Copiar"},{"type":"element","tagName":"span","properties":{"style":"color:red"},"children":[{"type":"text","value":"(Importante)"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"En un principio esto puede no parecer nada, estamos hablando de copiar un array o slice en otro......bueno pues no es tan simple, ¿recordáis lo que comentamos en el post anterior sobre tamaño y capacidad? Por refrescar rápidamente, el "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"tamaño"}]},{"type":"text","value":" era la cantidad de elementos que tenia un slice o array y la "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"capacidad"}]},{"type":"text","value":" la reserva de elementos que puede contener, es decir, la cantidad máxima de elementos que puede tener. Recordemos que Go lo que hace es reservar un espacio en memoria para almacenar una cantidad aproximada de datos, lo "},{"type":"element","tagName":"span","properties":{"style":"color:red"},"children":[{"type":"text","value":"importante"}]},{"type":"text","value":" venia a la hora de aumentar, como tal el "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"slice"}]},{"type":"text","value":" comentamos que al aumentar lo que hacia era reservarse el doble de la capacidad que tenia anteriormente. Esto con slices pequeños esta muy bien, pero ¿y si tenemos un slice de 1000 elementos? En cuanto añadamos 1 más se reservara un espacio de 2000."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Pues bien con este escenario tenemos la accion de "},{"type":"element","tagName":"span","properties":{"style":"color:red"},"children":[{"type":"text","value":"copiar"}]},{"type":"text","value":" como solución, lo que hacemos es copiar un array en otro con la capacidad ajustada a lo que queramos, la forma de usarlo es simple:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"copy(destino, origen)\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Bastante simple no? Pues veamos un ejemplo y apliquemos un poco de lógica para optimizar el consumo:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"//Creamos dos slices\nslice := []int{1, 2, 3, 4}\ncopia := make([]int, 4)\n\ncopy(copia, slice)\n\nfmt.Println(slice)\nfmt.Println(copia)\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Como vemos hemos creado un slice con la forma corta, con contenido, y otro vacio con un tamaño y capacidad de 4. Si imprimimos el contenido todo estaría normal, pero un detalle a tener en cuenta es que realmente "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"copy"}]},{"type":"text","value":" tiene en cuenta la capacidad del slice de destino (en este caso copia), como le hemos puesto una capacidad de 4, nos copia todo el contenido. Pongamos un ejemplo si ponemos menos:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"//Si cambiaramos copia con otra longitud\ncopia2 := make([]int, 2)\ncopy(copia2, slice)\nfmt.Println(slice)\nfmt.Println(copia2)\n//Veriamos como solo nos copia 2 elementos, \n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Lo mejor es controlar el tamaño(no la capacidad ojo), del slice origen y usar eso para crear el destino:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"//para no equivocarnos lo ideal seria\ncopia3 := make([]int, len(slice))\ncopy(copia3, slice)\n\nfmt.Println(slice)\nfmt.Println(copia3)\n//Con esto si cambia el tamaño del slice la copia tambien.\n\n//Como buena practica, aunque segun el entorno, es añadir el doble del tamaño a la capacidad\ncopia4 := make([]int, len(slice), len(slice)*2) //O con la capacidad segun el caso\n    \ncopy(copia4, slice)\nfmt.Println(slice)\nfmt.Println(copia4)\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Bueno creo que por el momento vamos a dejar los "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"arrays"}]},{"type":"text","value":" y "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"slices"}]},{"type":"text","value":" para continuar con otras cosas, recordar mirar el link "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/golang/go/wiki/SliceTricks"},"children":[{"type":"text","value":"SliceTricks"}]},{"type":"text","value":" y en otro de mis post tengo algo mas de trabajo con arrays: "},{"type":"element","tagName":"a","properties":{"href":"/go-tricks-i-array-contains/"},"children":[{"type":"text","value":"Go Tricks I"}]}]},{"type":"text","value":"\n"},{"type":"comment","value":"kg-card-end: markdown"}],"data":{"quirksMode":false}},"tableOfContents":[{"id":"recorrerunarrayoslice","heading":"Recorrer un array o slice"},{"id":"separandounarray","heading":"Separando un array"},{"id":"tamaoycapacidad","heading":"Tamaño y Capacidad"},{"id":"aadir","heading":"Añadir"},{"id":"eliminar","heading":"Eliminar"},{"id":"copiarspanstylecolorredimportantespan","heading":"Copiar(Importante)"}]},"featureImageSharp":{"base":"Untitled-3.png","publicURL":"/static/4c2a69b59a578389653f7d3cb966f439/Untitled-3.png","imageMeta":{"width":649,"height":244},"childImageSharp":{"fluid":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAABr0lEQVQoz22RPWhTURiGP+29N/eec3/aK1FjI9RBm3aSSBVBDVSzOGpwiMEhKopmsCnYyUVQwS5WxKU6iGBwdOrQqZOD+EO1HYo/mCBtySSC6+O5CQVjHF7ecw7veb6Xc0RrTa8USnV9S57ZZ2LF3rTqeBwqhiIf3++X9AO3YN11AlfGx7KKyTGX4nhXx/YJg9pGZBuOYxs5WJbVC1QdQBfm6oAwCnl+wWFixDMXPbZbGjulicx58dQko6MHKBQK5HK5jvL5/D8NDcz3NQOO4khGaJSElxXh4knFiaMZTh/22b/HwbYdpms1zpVKTNXrlMtlKpUK1Wq1v2ECVdrHPVPi+N0pns2eZ/7FNFdeP+FVY4a5xzfZcf8BA9fr7B4eZjCKSKfTZLNZ4jj+D9B1CXbuQu495OzaBt/ffWJh5RvF5m9azTbrq2tMfN1E5uZRQYhn8q7nkUql8Iz3ApN2QUAggly6xsjndRY32zz68J6Dtcs8ffuG280NrC9trOpVfJPTYdjzoX1vmEzVJmjfmEFaP5HlJoeWllhuzFJYXEA+tpAfv7Bu3enkkrz6i/EHdxf7UmCHE+cAAAAASUVORK5CYII=","aspectRatio":2.6515151515151514,"src":"/static/4c2a69b59a578389653f7d3cb966f439/d382d/Untitled-3.png","srcSet":"/static/4c2a69b59a578389653f7d3cb966f439/847ef/Untitled-3.png 175w,\n/static/4c2a69b59a578389653f7d3cb966f439/91cba/Untitled-3.png 350w,\n/static/4c2a69b59a578389653f7d3cb966f439/d382d/Untitled-3.png 649w","srcWebp":"/static/4c2a69b59a578389653f7d3cb966f439/10386/Untitled-3.webp","srcSetWebp":"/static/4c2a69b59a578389653f7d3cb966f439/9fca7/Untitled-3.webp 175w,\n/static/4c2a69b59a578389653f7d3cb966f439/37a4e/Untitled-3.webp 350w,\n/static/4c2a69b59a578389653f7d3cb966f439/10386/Untitled-3.webp 649w","sizes":"(max-width: 649px) 100vw, 649px"}}}}},{"node":{"id":"Ghost__Post__5a338158333e0f134c248f14","title":"Go Tricks (I):  Array contains","slug":"go-tricks-i-array-contains","featured":false,"feature_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Untitled-2.png","excerpt":"Comienzo sección nueva, en este caso son pequeños post que trataran sobre algún\ntruco para trabajar con Go, como todo existen varias formas de hacer, estas\nserán solo algunas posibles no siempre serán las mejores pero seguro que\nfuncionan ;)\n\nEn este primer post vamos a ver como comprobar si un elemento existe dentro de\nun array(o slice), lo veremos con strings pero puede ser con cualquier\ntipo(primitivo por lo menos)\n\nComo sabemos no tenemos forma directa en Go de comprobar si algo existe dentr","custom_excerpt":null,"visibility":"public","created_at_pretty":"12 Jul 2017","published_at_pretty":"13 Jul 2017","updated_at_pretty":"11 Oct 2017","created_at":"2017-07-12T21:09:31.000+02:00","published_at":"2017-07-13T11:00:34.000+02:00","updated_at":"2017-10-11T13:45:36.000+02:00","meta_title":null,"meta_description":null,"og_description":null,"og_image":null,"og_title":null,"twitter_description":null,"twitter_image":null,"twitter_title":null,"authors":[{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":null}],"primary_author":{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":{"base":"Perfil.jpg","publicURL":"/static/b0de6281fb28a266510b3b09b9243e5a/Perfil.jpg","imageMeta":{"width":307,"height":307},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAUDBAb/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAGzw6zC6zHn+cLYP//EAB0QAAICAQUAAAAAAAAAAAAAAAEDAAIEEyEiIzL/2gAIAQEAAQUCifca8KgcKWVfUpkHsG5pxX//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/AR//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/AR//xAAdEAACAgEFAAAAAAAAAAAAAAAAARARcQISIUFR/9oACAEBAAY/AhU88xkb7N06a8P/xAAcEAEAAwEAAwEAAAAAAAAAAAABABEhMUFRYXH/2gAIAQEAAT8hR2pq40aqb+xIAeXibhW9JXr8joF4TBcSNe0//9oADAMBAAIAAwAAABDzDwD/xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/EB//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/EB//xAAcEAEAAgIDAQAAAAAAAAAAAAABABEhUTFhcfD/2gAIAQEAAT8QyItrELaTlatLwU63MvEW6vUNdy4LZQDn7iVApV9VLtANdWwKkuYq4Er1VZ//2Q==","aspectRatio":1,"src":"/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg","srcSet":"/static/b0de6281fb28a266510b3b09b9243e5a/f340b/Perfil.jpg 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/22d64/Perfil.jpg 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/aa249/Perfil.jpg 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/0dc33/Perfil.jpg 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/60667/Perfil.jpg 307w","srcWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp","srcSetWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/59cda/Perfil.webp 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/7da75/Perfil.webp 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f282e/Perfil.webp 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/a7b21/Perfil.webp 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f59af/Perfil.webp 307w","sizes":"(max-width: 110px) 100vw, 110px"}}}},"primary_tag":{"slug":"go","url":"https://jlgarcia.fulldev.ninja/tag/go/","name":"Go","visibility":"public","feature_image":null,"description":null,"meta_title":"Golang Ninjas","meta_description":"Aprenderemos a usar el nuevo lenguaje de Google para backend desde lo más básico a temas avanzados como concurrencia o api rest.","featureImageSharp":null},"tags":[{"slug":"go","url":"https://jlgarcia.fulldev.ninja/tag/go/","name":"Go","visibility":"public","feature_image":null,"description":null,"meta_title":"Golang Ninjas","meta_description":"Aprenderemos a usar el nuevo lenguaje de Google para backend desde lo más básico a temas avanzados como concurrencia o api rest.","featureImageSharp":null},{"slug":"golang","url":"https://jlgarcia.fulldev.ninja/tag/golang/","name":"Golang","visibility":"public","feature_image":null,"description":null,"meta_title":"Golang Ninjas","meta_description":"Aprenderemos a usar el nuevo lenguaje de Google para backend desde lo más básico a temas avanzados como concurrencia o api rest.","featureImageSharp":null}],"plaintext":"Comienzo sección nueva, en este caso son pequeños post que trataran sobre algún\ntruco para trabajar con Go, como todo existen varias formas de hacer, estas\nserán solo algunas posibles no siempre serán las mejores pero seguro que\nfuncionan ;)\n\nEn este primer post vamos a ver como comprobar si un elemento existe dentro de\nun array(o slice), lo veremos con strings pero puede ser con cualquier\ntipo(primitivo por lo menos)\n\nComo sabemos no tenemos forma directa en Go de comprobar si algo existe dentro\nde un array por lo que debemos implementarlo nosotros.\nUna forma de hacerlo es la habitual de recorrer el array e ir comprobando pero\nrealmente tenemos un par de formas(mínimo) más que yo creo que pueden ser más\neficientes, aunque siempre depende del caso concreto.\n\nPrimera:\nVeamos una típica recorriendo el array\n\nlist := []string{\"a\", \"z\", \"j\", \"f\", \"i\", \"v\", \"r\", \"c\", \"l\", \"p\", \"h\", \"w\", \"k\", \"e\", \"u\", \"s\", \"b\"}\n\nfor _, v := range list {\n if v == \"b\" {\t\t\t\t\t\n      fmt.Println(\"Existe\")\n      break\n }\n}\n\n\nMétodo bastante sencillo, recorremos el array y comprobamos si es lo que\nbuscamos, en cuanto lo encuetre salimos del for. Es bastante rápido la verdad.\n\nSegunda:\nlist := []string{\"a\", \"x\", \"z\", \"j\", \"f\", \"i\", \"v\", \"r\", \"c\", \"l\", \"p\", \"h\", \"w\", \"k\", \"e\", \"u\", \"s\", \"b\"}\n\nset := make(map[string]bool)\n\nfor _, v := range list {\n   set[v] = true\n}\n\nfmt.Println(set[\"b\"])\n\n\nTenemos una array de strings desordenado, lo que hacemos es crear un map(lo que\nseria un diccionario en otros lenguajes), de clave=valor donde la clave es el\ncontenido del array, y como valor le he puesto true, para que cuando comprobemos\nque existe muestre un true(aunque eso pasaria con todos), es un poquito de\nazuquitar visual que hemos puesto. Realmente nos pasaria lo mismo si intentamos\nasignar el valor de forma corta, como tal recordar que los maps al asignarlos a\notra variable nueva devuelven realmente 2 valores, el contenido del map y si\nexiste o no.\n\nComo veis bastante sencillo, tenemos un for si o si pero es bastante rápido.\nFijaos que le he puesto el último valor con la idea de que al final haremos\npruebas de cuanto tarda cada uno.\n\nTercera:\nlist := []string{\"a\", \"x\", \"z\", \"j\", \"f\", \"i\", \"v\", \"r\", \"c\", \"l\", \"p\", \"h\", \"w\", \"k\", \"e\", \"u\", \"s\", \"b\"}\n\nsort.Strings(list)\ni := sort.SearchStrings(list, \"b\")\n\nfmt.Println(list[i] == \"b\")\n\n\nLo primero que hacemos es ordenar el array y luego nos valemos del método \nSearchStrings(tiene search de todo) que tiene el objeto sort, le pasamos el\narray y lo que queremos buscar y nos devuelve la posición en la que se\nencuentra. A continuación comprobamos si el array tiene en la posición recibida\nel string que buscamos y voilá.\nOJO!! Hacemos la comprobación de list[i] == \"b\" porque el método SearchStrings\ndevuelve la posición donde deberiamos insertar el elemento en el caso de que no\nexista para que este ordenado directamente al añadirlo\n\nEsta forma a mi me gusta más pero en grandes cantidades de datos realmente\ntendriamos que probar su eficienca\n\nPruebas VERSUS\nVamos a ver la diferencia de lo que tarda cada uno, esto no es del todo válido\nya que depende de muchos factores pero es solo por ver lo que podria ser un\nacercamiento.\nVamos a crear un bucle rápido con cada tipo, que nos muestre el tiempo que ha\ntardado, pondremos unas 50 ejecuciones de cada uno para ver un poco la media,\npero siempre tener en cuenta que afecta la cantidad de código que tengamos un\nsimple Print puede alterar los valores:\n\nPrimer método\nj := 0\nfor {\n  t1 := time.Now()\n  list := []string{\"a\", \"z\", \"j\", \"f\", \"i\", \"v\", \"r\", \"c\", \n\"l\", \"p\", \"h\", \"w\", \"k\", \"e\", \"u\", \"s\", \"b\"}\n\t\nfor _, v := range list {\n  if v == \"b\" {\n    //Aqui podriamos hacer que muestre true o algo asi\n    \tbreak\n    }\n}\n\nfmt.Println(\"Tiempo total: \", time.Since(t1))\n\nif j == 50 {\n  break\n}\nj++\n\n\nSeguiremos la misma linea para los 3, creamos una especie de bucle while en el\nque cuando sea 50 la variable j se salga de la funcion.\nEsta nos daria algo parecido a esto:\n\nLa primera ejecución tarda un poco mas y luego se mantiene, muy rápido no??(el\narray es muy pequeño jejejejje)\n\nSegundo método:\nj := 0\n\nfor {\n  t1 := time.Now()\n  list := []string{\"a\", \"z\", \"j\", \"f\", \"i\", \"v\", \"r\", \"c\", \"l\", \"p\", \"h\", \"w\", \"k\", \"e\", \"u\", \"s\", \"b\"}\n\nset := make(map[string]bool)\nfor _, v := range list {\n   set[v] = true\n}\n_ = set[\"b\"]\n\nfmt.Println(\"Tiempo total: \", time.Since(t1))\n\nif j == 50 {\n  break\n}\nj++\n\n\nNos da unos tiempos de este estilo\n\nBien aqui vemos que hemos bastante mas lentos en comparación, le he puesto el _\n= set[\"b\"] para simular que haciamos algo para comprobar.\nEste método tiene una ventaja, y es que si queremos buscar algo más ya lo\ntenemos en el map set. Como desventaja es que posiblemente consumamos recursos\ninnecesariamente.\n\nTercer Método:\nj := 0\n\nfor {\n  t1 := time.Now()\n  list := []string{\"a\", \"z\", \"j\", \"f\", \"i\", \"v\", \"r\", \"c\", \"l\", \"p\", \"h\", \"w\", \"k\", \"e\", \"u\", \"s\", \"b\"}\n\n  sort.Strings(list)\n  i := sort.SearchStrings(list, \"b\")\n  _ = (list[i] == \"b\")\n  fmt.Println(\"Tiempo total: \", time.Since(t1))\n\nif j == 50 {\n  break\n}\nj++\n\n\nY con este ultimo obtenemos:\n\nVemos que es más rápido que el segundo pero menos que el primero. Como tal con\neste método si tenemos que realizar otra búsqueda como ya estaria ordenado seria\nmás rápida, he probado y salen unos tiempos como estos:\n\nComo veis llegamos a los nanosegundos, que no esta mal.\n\nAl final todo esto es orientativo, siempre dependerá del entorno y la cantidad\nde elementos que tenga el array. Es bastante probable que la primera forma sea\nla más rápida en la mayoría de los entornos pero al final deberemos valorarlo en\nel momento. También es cierto que es más fácil crearnos un método de utilidad\ncon la primera opción que con el resto, podríamos generalizar usando interface o\ncualquier cosa que se nos ocurra. Siendo esto bastante útil si pensamos en la\nconcurrencia como Go funciona con copias de elementos(a no ser que usemos\npunteros) no tendríamos \"condiciones de carrera\"(race conditions) a la hora de\nacceder a los elementos.\n\nEspero que os haya parecido interesante, nos vemos en el siguiente NINJA POST :)\n\nP.D: Para el que no sepa lo que es el race condition, básicamente es la\nposibilidad de que se este accediendo al mismo elemento y al mismo tiempo, lo\nque generaría varios problemas(cosa que en Go si trabajamos con copias no\ntendríamos)","html":"<!--kg-card-begin: markdown--><p>Comienzo sección nueva, en este caso son pequeños post que trataran sobre algún truco para trabajar con Go, como todo existen varias formas de hacer, estas serán solo algunas posibles no siempre serán las mejores pero seguro que funcionan ;)</p>\n<p>En este primer post vamos a ver como comprobar si un elemento existe dentro de un <strong>array(o slice)</strong>, lo veremos con strings pero puede ser con cualquier tipo(primitivo por lo menos)</p>\n<p>Como sabemos no tenemos forma directa en Go de comprobar si algo existe dentro de un array por lo que debemos implementarlo nosotros.<br>\nUna forma de hacerlo es la habitual de recorrer el array e ir comprobando pero realmente tenemos un par de formas(mínimo) más que yo creo que pueden ser más eficientes, aunque siempre depende del caso concreto.</p>\n<h3 id=\"primera\">Primera:</h3>\n<p>Veamos una típica recorriendo el array</p>\n<pre><code>list := []string{&quot;a&quot;, &quot;z&quot;, &quot;j&quot;, &quot;f&quot;, &quot;i&quot;, &quot;v&quot;, &quot;r&quot;, &quot;c&quot;, &quot;l&quot;, &quot;p&quot;, &quot;h&quot;, &quot;w&quot;, &quot;k&quot;, &quot;e&quot;, &quot;u&quot;, &quot;s&quot;, &quot;b&quot;}\n\nfor _, v := range list {\n if v == &quot;b&quot; {\t\t\t\t\t\n      fmt.Println(&quot;Existe&quot;)\n      break\n }\n}\n</code></pre>\n<p>Método bastante sencillo, recorremos el array y comprobamos si es lo que buscamos, en cuanto lo encuetre salimos del for. Es bastante rápido la verdad.</p>\n<h3 id=\"segunda\">Segunda:</h3>\n<pre><code>list := []string{&quot;a&quot;, &quot;x&quot;, &quot;z&quot;, &quot;j&quot;, &quot;f&quot;, &quot;i&quot;, &quot;v&quot;, &quot;r&quot;, &quot;c&quot;, &quot;l&quot;, &quot;p&quot;, &quot;h&quot;, &quot;w&quot;, &quot;k&quot;, &quot;e&quot;, &quot;u&quot;, &quot;s&quot;, &quot;b&quot;}\n\nset := make(map[string]bool)\n\nfor _, v := range list {\n   set[v] = true\n}\n\nfmt.Println(set[&quot;b&quot;])\n</code></pre>\n<p>Tenemos una array de strings desordenado, lo que hacemos es  crear un <strong>map</strong>(lo que seria un diccionario en otros lenguajes), de clave=valor donde la clave es el contenido del array, y como valor le he puesto true, para que cuando comprobemos que existe muestre un <strong>true</strong>(aunque eso pasaria con todos), es un poquito de azuquitar visual que hemos puesto. Realmente nos pasaria lo mismo si intentamos asignar el valor de forma corta, como tal recordar que los maps al asignarlos a otra variable nueva devuelven realmente 2 valores, el contenido del map y si existe o no.</p>\n<p>Como veis bastante sencillo, tenemos un for si o si pero es bastante rápido. Fijaos que le he puesto el último valor con la idea de que al final haremos pruebas de cuanto tarda cada uno.</p>\n<h3 id=\"tercera\">Tercera:</h3>\n<pre><code>list := []string{&quot;a&quot;, &quot;x&quot;, &quot;z&quot;, &quot;j&quot;, &quot;f&quot;, &quot;i&quot;, &quot;v&quot;, &quot;r&quot;, &quot;c&quot;, &quot;l&quot;, &quot;p&quot;, &quot;h&quot;, &quot;w&quot;, &quot;k&quot;, &quot;e&quot;, &quot;u&quot;, &quot;s&quot;, &quot;b&quot;}\n\nsort.Strings(list)\ni := sort.SearchStrings(list, &quot;b&quot;)\n\nfmt.Println(list[i] == &quot;b&quot;)\n</code></pre>\n<p>Lo primero que hacemos es ordenar el array y luego nos valemos del método <strong>SearchStrings</strong>(tiene search de todo) que tiene el objeto sort, le pasamos el array y lo que queremos buscar y nos devuelve la posición en la que se encuentra. A continuación comprobamos si el array tiene en la posición recibida el string que buscamos y voilá.<br>\n<strong>OJO!! Hacemos la comprobación de list[i] == &quot;b&quot; porque el método SearchStrings devuelve la posición donde deberiamos insertar el elemento en el caso de que no exista para que este ordenado directamente al añadirlo</strong></p>\n<p>Esta forma a mi me gusta más pero en grandes cantidades de datos realmente tendriamos que probar su eficienca</p>\n<h2 id=\"pruebasversus\">Pruebas VERSUS</h2>\n<p>Vamos a ver la diferencia de lo que tarda cada uno, esto no es del todo válido ya que depende de muchos factores pero es solo por ver lo que podria ser un acercamiento.<br>\nVamos a crear un bucle rápido con cada tipo, que nos muestre el tiempo que ha tardado, pondremos unas 50 ejecuciones de cada uno para ver un poco la media, pero siempre tener en cuenta que afecta la cantidad de código que tengamos un simple <strong>Print</strong> puede alterar los valores:</p>\n<h3 id=\"primermtodo\">Primer método</h3>\n<pre><code>j := 0\nfor {\n  t1 := time.Now()\n  list := []string{&quot;a&quot;, &quot;z&quot;, &quot;j&quot;, &quot;f&quot;, &quot;i&quot;, &quot;v&quot;, &quot;r&quot;, &quot;c&quot;, \n&quot;l&quot;, &quot;p&quot;, &quot;h&quot;, &quot;w&quot;, &quot;k&quot;, &quot;e&quot;, &quot;u&quot;, &quot;s&quot;, &quot;b&quot;}\n\t\nfor _, v := range list {\n  if v == &quot;b&quot; {\n    //Aqui podriamos hacer que muestre true o algo asi\n    \tbreak\n    }\n}\n\nfmt.Println(&quot;Tiempo total: &quot;, time.Since(t1))\n\nif j == 50 {\n  break\n}\nj++\n</code></pre>\n<p>Seguiremos la misma linea para los 3, creamos una especie de bucle while en el que cuando sea 50  la variable <strong>j</strong> se salga de la funcion.<br>\nEsta nos daria algo parecido a esto:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-13-at-09.07.51.png\" alt=\"\"><br>\nLa primera ejecución tarda un poco mas y luego se mantiene, muy rápido no??(el array es muy pequeño jejejejje)</p>\n<h3 id=\"segundomtodo\">Segundo método:</h3>\n<pre><code>j := 0\n\nfor {\n  t1 := time.Now()\n  list := []string{&quot;a&quot;, &quot;z&quot;, &quot;j&quot;, &quot;f&quot;, &quot;i&quot;, &quot;v&quot;, &quot;r&quot;, &quot;c&quot;, &quot;l&quot;, &quot;p&quot;, &quot;h&quot;, &quot;w&quot;, &quot;k&quot;, &quot;e&quot;, &quot;u&quot;, &quot;s&quot;, &quot;b&quot;}\n\nset := make(map[string]bool)\nfor _, v := range list {\n   set[v] = true\n}\n_ = set[&quot;b&quot;]\n\nfmt.Println(&quot;Tiempo total: &quot;, time.Since(t1))\n\nif j == 50 {\n  break\n}\nj++\n</code></pre>\n<p>Nos da unos tiempos de este estilo<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-13-at-09.12.25.png\" alt=\"\"><br>\nBien aqui vemos que hemos bastante mas lentos en comparación, le he puesto el <strong>_ = set[&quot;b&quot;]</strong> para simular que haciamos algo para comprobar.<br>\nEste método tiene una ventaja, y es que si queremos buscar algo más ya lo tenemos en el <strong>map</strong> set. Como desventaja es que posiblemente consumamos recursos innecesariamente.</p>\n<h3 id=\"tercermtodo\">Tercer Método:</h3>\n<pre><code>j := 0\n\nfor {\n  t1 := time.Now()\n  list := []string{&quot;a&quot;, &quot;z&quot;, &quot;j&quot;, &quot;f&quot;, &quot;i&quot;, &quot;v&quot;, &quot;r&quot;, &quot;c&quot;, &quot;l&quot;, &quot;p&quot;, &quot;h&quot;, &quot;w&quot;, &quot;k&quot;, &quot;e&quot;, &quot;u&quot;, &quot;s&quot;, &quot;b&quot;}\n\n  sort.Strings(list)\n  i := sort.SearchStrings(list, &quot;b&quot;)\n  _ = (list[i] == &quot;b&quot;)\n  fmt.Println(&quot;Tiempo total: &quot;, time.Since(t1))\n\nif j == 50 {\n  break\n}\nj++\n</code></pre>\n<p>Y con este ultimo obtenemos:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-13-at-09.18.12.png\" alt=\"\"><br>\nVemos que es más rápido que el segundo pero menos que el primero. Como tal con este método si tenemos que realizar otra búsqueda como ya estaria ordenado seria más rápida, he probado y salen unos tiempos como estos:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-13-at-09.20.45.png\" alt=\"\"><br>\nComo veis llegamos a los nanosegundos, que no esta mal.</p>\n<p>Al final todo esto es orientativo, siempre dependerá del entorno y la cantidad de elementos que tenga el array. Es bastante probable que la primera forma sea la más rápida en la mayoría de los entornos pero al final deberemos valorarlo en el momento. También es cierto que es más fácil crearnos un método de utilidad con la primera opción que con el resto, podríamos generalizar usando <strong>interface</strong> o cualquier cosa que se nos ocurra. Siendo esto bastante útil si pensamos en la concurrencia como Go funciona con copias de elementos(a no ser que usemos punteros) no tendríamos <em>&quot;condiciones de carrera&quot;</em>(race conditions) a la hora de acceder a los elementos.</p>\n<p>Espero que os haya parecido interesante, nos vemos en el siguiente NINJA POST :)</p>\n<p>P.D: Para el que no sepa lo que es el race condition, básicamente es la posibilidad de que se este accediendo al mismo elemento y al mismo tiempo, lo que generaría varios problemas(cosa que en Go si trabajamos con copias no tendríamos)</p>\n<!--kg-card-end: markdown-->","url":"https://jlgarcia.fulldev.ninja/go-tricks-i-array-contains/","canonical_url":null,"uuid":"5cb27cd0-996d-4bc8-ae3c-d717d236f9a6","codeinjection_foot":null,"codeinjection_head":null,"codeinjection_styles":null,"comment_id":"32","reading_time":6,"send_email_when_published":false,"email_subject":null,"childHtmlRehype":{"html":"<!--kg-card-begin: markdown--><p>Comienzo sección nueva, en este caso son pequeños post que trataran sobre algún truco para trabajar con Go, como todo existen varias formas de hacer, estas serán solo algunas posibles no siempre serán las mejores pero seguro que funcionan ;)</p>\n<p>En este primer post vamos a ver como comprobar si un elemento existe dentro de un <strong>array(o slice)</strong>, lo veremos con strings pero puede ser con cualquier tipo(primitivo por lo menos)</p>\n<p>Como sabemos no tenemos forma directa en Go de comprobar si algo existe dentro de un array por lo que debemos implementarlo nosotros.<br>\nUna forma de hacerlo es la habitual de recorrer el array e ir comprobando pero realmente tenemos un par de formas(mínimo) más que yo creo que pueden ser más eficientes, aunque siempre depende del caso concreto.</p>\n<h3 id=\"primera\">Primera:</h3>\n<p>Veamos una típica recorriendo el array</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">list := []string{\"a\", \"z\", \"j\", \"f\", \"i\", \"v\", \"r\", \"c\", \"l\", \"p\", \"h\", \"w\", \"k\", \"e\", \"u\", \"s\", \"b\"}\n\nfor _, v := range list {\n if v == \"b\" {\t\t\t\t\t\n      fmt.Println(\"Existe\")\n      break\n }\n}\n</code></pre></div>\n<p>Método bastante sencillo, recorremos el array y comprobamos si es lo que buscamos, en cuanto lo encuetre salimos del for. Es bastante rápido la verdad.</p>\n<h3 id=\"segunda\">Segunda:</h3>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">list := []string{\"a\", \"x\", \"z\", \"j\", \"f\", \"i\", \"v\", \"r\", \"c\", \"l\", \"p\", \"h\", \"w\", \"k\", \"e\", \"u\", \"s\", \"b\"}\n\nset := make(map[string]bool)\n\nfor _, v := range list {\n   set[v] = true\n}\n\nfmt.Println(set[\"b\"])\n</code></pre></div>\n<p>Tenemos una array de strings desordenado, lo que hacemos es  crear un <strong>map</strong>(lo que seria un diccionario en otros lenguajes), de clave=valor donde la clave es el contenido del array, y como valor le he puesto true, para que cuando comprobemos que existe muestre un <strong>true</strong>(aunque eso pasaria con todos), es un poquito de azuquitar visual que hemos puesto. Realmente nos pasaria lo mismo si intentamos asignar el valor de forma corta, como tal recordar que los maps al asignarlos a otra variable nueva devuelven realmente 2 valores, el contenido del map y si existe o no.</p>\n<p>Como veis bastante sencillo, tenemos un for si o si pero es bastante rápido. Fijaos que le he puesto el último valor con la idea de que al final haremos pruebas de cuanto tarda cada uno.</p>\n<h3 id=\"tercera\">Tercera:</h3>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">list := []string{\"a\", \"x\", \"z\", \"j\", \"f\", \"i\", \"v\", \"r\", \"c\", \"l\", \"p\", \"h\", \"w\", \"k\", \"e\", \"u\", \"s\", \"b\"}\n\nsort.Strings(list)\ni := sort.SearchStrings(list, \"b\")\n\nfmt.Println(list[i] == \"b\")\n</code></pre></div>\n<p>Lo primero que hacemos es ordenar el array y luego nos valemos del método <strong>SearchStrings</strong>(tiene search de todo) que tiene el objeto sort, le pasamos el array y lo que queremos buscar y nos devuelve la posición en la que se encuentra. A continuación comprobamos si el array tiene en la posición recibida el string que buscamos y voilá.<br>\n<strong>OJO!! Hacemos la comprobación de list[i] == \"b\" porque el método SearchStrings devuelve la posición donde deberiamos insertar el elemento en el caso de que no exista para que este ordenado directamente al añadirlo</strong></p>\n<p>Esta forma a mi me gusta más pero en grandes cantidades de datos realmente tendriamos que probar su eficienca</p>\n<h2 id=\"pruebasversus\">Pruebas VERSUS</h2>\n<p>Vamos a ver la diferencia de lo que tarda cada uno, esto no es del todo válido ya que depende de muchos factores pero es solo por ver lo que podria ser un acercamiento.<br>\nVamos a crear un bucle rápido con cada tipo, que nos muestre el tiempo que ha tardado, pondremos unas 50 ejecuciones de cada uno para ver un poco la media, pero siempre tener en cuenta que afecta la cantidad de código que tengamos un simple <strong>Print</strong> puede alterar los valores:</p>\n<h3 id=\"primermtodo\">Primer método</h3>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">j := 0\nfor {\n  t1 := time.Now()\n  list := []string{\"a\", \"z\", \"j\", \"f\", \"i\", \"v\", \"r\", \"c\", \n\"l\", \"p\", \"h\", \"w\", \"k\", \"e\", \"u\", \"s\", \"b\"}\n\t\nfor _, v := range list {\n  if v == \"b\" {\n    //Aqui podriamos hacer que muestre true o algo asi\n    \tbreak\n    }\n}\n\nfmt.Println(\"Tiempo total: \", time.Since(t1))\n\nif j == 50 {\n  break\n}\nj++\n</code></pre></div>\n<p>Seguiremos la misma linea para los 3, creamos una especie de bucle while en el que cuando sea 50  la variable <strong>j</strong> se salga de la funcion.<br>\nEsta nos daria algo parecido a esto:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-13-at-09.07.51.png\" alt=\"\"><br>\nLa primera ejecución tarda un poco mas y luego se mantiene, muy rápido no??(el array es muy pequeño jejejejje)</p>\n<h3 id=\"segundomtodo\">Segundo método:</h3>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">j := 0\n\nfor {\n  t1 := time.Now()\n  list := []string{\"a\", \"z\", \"j\", \"f\", \"i\", \"v\", \"r\", \"c\", \"l\", \"p\", \"h\", \"w\", \"k\", \"e\", \"u\", \"s\", \"b\"}\n\nset := make(map[string]bool)\nfor _, v := range list {\n   set[v] = true\n}\n_ = set[\"b\"]\n\nfmt.Println(\"Tiempo total: \", time.Since(t1))\n\nif j == 50 {\n  break\n}\nj++\n</code></pre></div>\n<p>Nos da unos tiempos de este estilo<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-13-at-09.12.25.png\" alt=\"\"><br>\nBien aqui vemos que hemos bastante mas lentos en comparación, le he puesto el <strong>_ = set[\"b\"]</strong> para simular que haciamos algo para comprobar.<br>\nEste método tiene una ventaja, y es que si queremos buscar algo más ya lo tenemos en el <strong>map</strong> set. Como desventaja es que posiblemente consumamos recursos innecesariamente.</p>\n<h3 id=\"tercermtodo\">Tercer Método:</h3>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">j := 0\n\nfor {\n  t1 := time.Now()\n  list := []string{\"a\", \"z\", \"j\", \"f\", \"i\", \"v\", \"r\", \"c\", \"l\", \"p\", \"h\", \"w\", \"k\", \"e\", \"u\", \"s\", \"b\"}\n\n  sort.Strings(list)\n  i := sort.SearchStrings(list, \"b\")\n  _ = (list[i] == \"b\")\n  fmt.Println(\"Tiempo total: \", time.Since(t1))\n\nif j == 50 {\n  break\n}\nj++\n</code></pre></div>\n<p>Y con este ultimo obtenemos:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-13-at-09.18.12.png\" alt=\"\"><br>\nVemos que es más rápido que el segundo pero menos que el primero. Como tal con este método si tenemos que realizar otra búsqueda como ya estaria ordenado seria más rápida, he probado y salen unos tiempos como estos:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-13-at-09.20.45.png\" alt=\"\"><br>\nComo veis llegamos a los nanosegundos, que no esta mal.</p>\n<p>Al final todo esto es orientativo, siempre dependerá del entorno y la cantidad de elementos que tenga el array. Es bastante probable que la primera forma sea la más rápida en la mayoría de los entornos pero al final deberemos valorarlo en el momento. También es cierto que es más fácil crearnos un método de utilidad con la primera opción que con el resto, podríamos generalizar usando <strong>interface</strong> o cualquier cosa que se nos ocurra. Siendo esto bastante útil si pensamos en la concurrencia como Go funciona con copias de elementos(a no ser que usemos punteros) no tendríamos <em>\"condiciones de carrera\"</em>(race conditions) a la hora de acceder a los elementos.</p>\n<p>Espero que os haya parecido interesante, nos vemos en el siguiente NINJA POST :)</p>\n<p>P.D: Para el que no sepa lo que es el race condition, básicamente es la posibilidad de que se este accediendo al mismo elemento y al mismo tiempo, lo que generaría varios problemas(cosa que en Go si trabajamos con copias no tendríamos)</p>\n<!--kg-card-end: markdown-->","htmlAst":{"type":"root","children":[{"type":"comment","value":"kg-card-begin: markdown"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Comienzo sección nueva, en este caso son pequeños post que trataran sobre algún truco para trabajar con Go, como todo existen varias formas de hacer, estas serán solo algunas posibles no siempre serán las mejores pero seguro que funcionan ;)"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"En este primer post vamos a ver como comprobar si un elemento existe dentro de un "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"array(o slice)"}]},{"type":"text","value":", lo veremos con strings pero puede ser con cualquier tipo(primitivo por lo menos)"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Como sabemos no tenemos forma directa en Go de comprobar si algo existe dentro de un array por lo que debemos implementarlo nosotros."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nUna forma de hacerlo es la habitual de recorrer el array e ir comprobando pero realmente tenemos un par de formas(mínimo) más que yo creo que pueden ser más eficientes, aunque siempre depende del caso concreto."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"primera"},"children":[{"type":"text","value":"Primera:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Veamos una típica recorriendo el array"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"list := []string{\"a\", \"z\", \"j\", \"f\", \"i\", \"v\", \"r\", \"c\", \"l\", \"p\", \"h\", \"w\", \"k\", \"e\", \"u\", \"s\", \"b\"}\n\nfor _, v := range list {\n if v == \"b\" {\t\t\t\t\t\n      fmt.Println(\"Existe\")\n      break\n }\n}\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Método bastante sencillo, recorremos el array y comprobamos si es lo que buscamos, en cuanto lo encuetre salimos del for. Es bastante rápido la verdad."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"segunda"},"children":[{"type":"text","value":"Segunda:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"list := []string{\"a\", \"x\", \"z\", \"j\", \"f\", \"i\", \"v\", \"r\", \"c\", \"l\", \"p\", \"h\", \"w\", \"k\", \"e\", \"u\", \"s\", \"b\"}\n\nset := make(map[string]bool)\n\nfor _, v := range list {\n   set[v] = true\n}\n\nfmt.Println(set[\"b\"])\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Tenemos una array de strings desordenado, lo que hacemos es  crear un "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"map"}]},{"type":"text","value":"(lo que seria un diccionario en otros lenguajes), de clave=valor donde la clave es el contenido del array, y como valor le he puesto true, para que cuando comprobemos que existe muestre un "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"true"}]},{"type":"text","value":"(aunque eso pasaria con todos), es un poquito de azuquitar visual que hemos puesto. Realmente nos pasaria lo mismo si intentamos asignar el valor de forma corta, como tal recordar que los maps al asignarlos a otra variable nueva devuelven realmente 2 valores, el contenido del map y si existe o no."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Como veis bastante sencillo, tenemos un for si o si pero es bastante rápido. Fijaos que le he puesto el último valor con la idea de que al final haremos pruebas de cuanto tarda cada uno."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"tercera"},"children":[{"type":"text","value":"Tercera:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"list := []string{\"a\", \"x\", \"z\", \"j\", \"f\", \"i\", \"v\", \"r\", \"c\", \"l\", \"p\", \"h\", \"w\", \"k\", \"e\", \"u\", \"s\", \"b\"}\n\nsort.Strings(list)\ni := sort.SearchStrings(list, \"b\")\n\nfmt.Println(list[i] == \"b\")\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Lo primero que hacemos es ordenar el array y luego nos valemos del método "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"SearchStrings"}]},{"type":"text","value":"(tiene search de todo) que tiene el objeto sort, le pasamos el array y lo que queremos buscar y nos devuelve la posición en la que se encuentra. A continuación comprobamos si el array tiene en la posición recibida el string que buscamos y voilá."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"OJO!! Hacemos la comprobación de list[i] == \"b\" porque el método SearchStrings devuelve la posición donde deberiamos insertar el elemento en el caso de que no exista para que este ordenado directamente al añadirlo"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Esta forma a mi me gusta más pero en grandes cantidades de datos realmente tendriamos que probar su eficienca"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"pruebasversus"},"children":[{"type":"text","value":"Pruebas VERSUS"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Vamos a ver la diferencia de lo que tarda cada uno, esto no es del todo válido ya que depende de muchos factores pero es solo por ver lo que podria ser un acercamiento."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nVamos a crear un bucle rápido con cada tipo, que nos muestre el tiempo que ha tardado, pondremos unas 50 ejecuciones de cada uno para ver un poco la media, pero siempre tener en cuenta que afecta la cantidad de código que tengamos un simple "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Print"}]},{"type":"text","value":" puede alterar los valores:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"primermtodo"},"children":[{"type":"text","value":"Primer método"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"j := 0\nfor {\n  t1 := time.Now()\n  list := []string{\"a\", \"z\", \"j\", \"f\", \"i\", \"v\", \"r\", \"c\", \n\"l\", \"p\", \"h\", \"w\", \"k\", \"e\", \"u\", \"s\", \"b\"}\n\t\nfor _, v := range list {\n  if v == \"b\" {\n    //Aqui podriamos hacer que muestre true o algo asi\n    \tbreak\n    }\n}\n\nfmt.Println(\"Tiempo total: \", time.Since(t1))\n\nif j == 50 {\n  break\n}\nj++\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Seguiremos la misma linea para los 3, creamos una especie de bucle while en el que cuando sea 50  la variable "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"j"}]},{"type":"text","value":" se salga de la funcion."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nEsta nos daria algo parecido a esto:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-13-at-09.07.51.png","alt":""},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nLa primera ejecución tarda un poco mas y luego se mantiene, muy rápido no??(el array es muy pequeño jejejejje)"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"segundomtodo"},"children":[{"type":"text","value":"Segundo método:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"j := 0\n\nfor {\n  t1 := time.Now()\n  list := []string{\"a\", \"z\", \"j\", \"f\", \"i\", \"v\", \"r\", \"c\", \"l\", \"p\", \"h\", \"w\", \"k\", \"e\", \"u\", \"s\", \"b\"}\n\nset := make(map[string]bool)\nfor _, v := range list {\n   set[v] = true\n}\n_ = set[\"b\"]\n\nfmt.Println(\"Tiempo total: \", time.Since(t1))\n\nif j == 50 {\n  break\n}\nj++\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Nos da unos tiempos de este estilo"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-13-at-09.12.25.png","alt":""},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nBien aqui vemos que hemos bastante mas lentos en comparación, le he puesto el "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"_ = set[\"b\"]"}]},{"type":"text","value":" para simular que haciamos algo para comprobar."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nEste método tiene una ventaja, y es que si queremos buscar algo más ya lo tenemos en el "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"map"}]},{"type":"text","value":" set. Como desventaja es que posiblemente consumamos recursos innecesariamente."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"tercermtodo"},"children":[{"type":"text","value":"Tercer Método:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"j := 0\n\nfor {\n  t1 := time.Now()\n  list := []string{\"a\", \"z\", \"j\", \"f\", \"i\", \"v\", \"r\", \"c\", \"l\", \"p\", \"h\", \"w\", \"k\", \"e\", \"u\", \"s\", \"b\"}\n\n  sort.Strings(list)\n  i := sort.SearchStrings(list, \"b\")\n  _ = (list[i] == \"b\")\n  fmt.Println(\"Tiempo total: \", time.Since(t1))\n\nif j == 50 {\n  break\n}\nj++\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Y con este ultimo obtenemos:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-13-at-09.18.12.png","alt":""},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nVemos que es más rápido que el segundo pero menos que el primero. Como tal con este método si tenemos que realizar otra búsqueda como ya estaria ordenado seria más rápida, he probado y salen unos tiempos como estos:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen-Shot-2017-07-13-at-09.20.45.png","alt":""},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nComo veis llegamos a los nanosegundos, que no esta mal."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Al final todo esto es orientativo, siempre dependerá del entorno y la cantidad de elementos que tenga el array. Es bastante probable que la primera forma sea la más rápida en la mayoría de los entornos pero al final deberemos valorarlo en el momento. También es cierto que es más fácil crearnos un método de utilidad con la primera opción que con el resto, podríamos generalizar usando "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"interface"}]},{"type":"text","value":" o cualquier cosa que se nos ocurra. Siendo esto bastante útil si pensamos en la concurrencia como Go funciona con copias de elementos(a no ser que usemos punteros) no tendríamos "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"\"condiciones de carrera\""}]},{"type":"text","value":"(race conditions) a la hora de acceder a los elementos."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Espero que os haya parecido interesante, nos vemos en el siguiente NINJA POST :)"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"P.D: Para el que no sepa lo que es el race condition, básicamente es la posibilidad de que se este accediendo al mismo elemento y al mismo tiempo, lo que generaría varios problemas(cosa que en Go si trabajamos con copias no tendríamos)"}]},{"type":"text","value":"\n"},{"type":"comment","value":"kg-card-end: markdown"}],"data":{"quirksMode":false}},"tableOfContents":[{"id":"primera","heading":"Primera:"},{"id":"segunda","heading":"Segunda:"},{"id":"tercera","heading":"Tercera:"},{"id":"pruebasversus","heading":"Pruebas VERSUS","items":[{"id":"primermtodo","heading":"Primer método"},{"id":"segundomtodo","heading":"Segundo método:"},{"id":"tercermtodo","heading":"Tercer Método:"}]}]},"featureImageSharp":{"base":"Untitled-2.png","publicURL":"/static/4c2a69b59a578389653f7d3cb966f439/Untitled-2.png","imageMeta":{"width":649,"height":244},"childImageSharp":{"fluid":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAABr0lEQVQoz22RPWhTURiGP+29N/eec3/aK1FjI9RBm3aSSBVBDVSzOGpwiMEhKopmsCnYyUVQwS5WxKU6iGBwdOrQqZOD+EO1HYo/mCBtySSC6+O5CQVjHF7ecw7veb6Xc0RrTa8USnV9S57ZZ2LF3rTqeBwqhiIf3++X9AO3YN11AlfGx7KKyTGX4nhXx/YJg9pGZBuOYxs5WJbVC1QdQBfm6oAwCnl+wWFixDMXPbZbGjulicx58dQko6MHKBQK5HK5jvL5/D8NDcz3NQOO4khGaJSElxXh4knFiaMZTh/22b/HwbYdpms1zpVKTNXrlMtlKpUK1Wq1v2ECVdrHPVPi+N0pns2eZ/7FNFdeP+FVY4a5xzfZcf8BA9fr7B4eZjCKSKfTZLNZ4jj+D9B1CXbuQu495OzaBt/ffWJh5RvF5m9azTbrq2tMfN1E5uZRQYhn8q7nkUql8Iz3ApN2QUAggly6xsjndRY32zz68J6Dtcs8ffuG280NrC9trOpVfJPTYdjzoX1vmEzVJmjfmEFaP5HlJoeWllhuzFJYXEA+tpAfv7Bu3enkkrz6i/EHdxf7UmCHE+cAAAAASUVORK5CYII=","aspectRatio":2.6515151515151514,"src":"/static/4c2a69b59a578389653f7d3cb966f439/d382d/Untitled-2.png","srcSet":"/static/4c2a69b59a578389653f7d3cb966f439/847ef/Untitled-2.png 175w,\n/static/4c2a69b59a578389653f7d3cb966f439/91cba/Untitled-2.png 350w,\n/static/4c2a69b59a578389653f7d3cb966f439/d382d/Untitled-2.png 649w","srcWebp":"/static/4c2a69b59a578389653f7d3cb966f439/10386/Untitled-2.webp","srcSetWebp":"/static/4c2a69b59a578389653f7d3cb966f439/9fca7/Untitled-2.webp 175w,\n/static/4c2a69b59a578389653f7d3cb966f439/37a4e/Untitled-2.webp 350w,\n/static/4c2a69b59a578389653f7d3cb966f439/10386/Untitled-2.webp 649w","sizes":"(max-width: 649px) 100vw, 649px"}}}}},{"node":{"id":"Ghost__Post__5a338158333e0f134c248f0c","title":"Go Go Power Ra....ah que no: Go Parte 3 - Arrays y Slices I","slug":"go-go-power-ra-ah-que-no-go-parte-3-arrays-y-slices-i","featured":false,"feature_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Untitled-2.png","excerpt":"En Go tenemos dos tipos de arrays o arreglos:\n\n * Los que llaman arrays, son arreglos con una cantidad definida de elementos,es\n   decir, tienen un tamaño fijo y no pueden crecer.\n   \n   \n * Los llamados slices, que son los arreglos o arrays más comunes, en los cuales\n   podemos añadir los elementos que queramos.\n   \n   \n\nY porque tenemos dos tipos? Pues básicamente es por el consumo de recursos, los \narrays definidos, solo se reservan los recursos que necesitan, los slices o\nllamemoslos arrays ","custom_excerpt":null,"visibility":"public","created_at_pretty":"3 Jul 2017","published_at_pretty":"11 Jul 2017","updated_at_pretty":"11 Oct 2017","created_at":"2017-07-03T21:39:27.000+02:00","published_at":"2017-07-11T22:11:39.000+02:00","updated_at":"2017-10-11T13:45:11.000+02:00","meta_title":null,"meta_description":null,"og_description":null,"og_image":null,"og_title":null,"twitter_description":null,"twitter_image":null,"twitter_title":null,"authors":[{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":null}],"primary_author":{"slug":"jlgarcia","url":"https://jlgarcia.fulldev.ninja/author/jlgarcia/","name":"Juan Luis Garcia Aparicio","bio":null,"cover_image":null,"profile_image":"https://jlgarcia.fulldev.ninja/assets/images/2017/12/Perfil.jpg","location":null,"website":null,"twitter":null,"facebook":null,"meta_title":null,"meta_description":null,"coverImageSharp":null,"profileImageSharp":{"base":"Perfil.jpg","publicURL":"/static/b0de6281fb28a266510b3b09b9243e5a/Perfil.jpg","imageMeta":{"width":307,"height":307},"childImageSharp":{"fluid":{"base64":"data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAUABQDASIAAhEBAxEB/8QAGAABAQEBAQAAAAAAAAAAAAAAAAUDBAb/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAGzw6zC6zHn+cLYP//EAB0QAAICAQUAAAAAAAAAAAAAAAEDAAIEEyEiIzL/2gAIAQEAAQUCifca8KgcKWVfUpkHsG5pxX//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/AR//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/AR//xAAdEAACAgEFAAAAAAAAAAAAAAAAARARcQISIUFR/9oACAEBAAY/AhU88xkb7N06a8P/xAAcEAEAAwEAAwEAAAAAAAAAAAABABEhMUFRYXH/2gAIAQEAAT8hR2pq40aqb+xIAeXibhW9JXr8joF4TBcSNe0//9oADAMBAAIAAwAAABDzDwD/xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAEDAQE/EB//xAAUEQEAAAAAAAAAAAAAAAAAAAAg/9oACAECAQE/EB//xAAcEAEAAgIDAQAAAAAAAAAAAAABABEhUTFhcfD/2gAIAQEAAT8QyItrELaTlatLwU63MvEW6vUNdy4LZQDn7iVApV9VLtANdWwKkuYq4Er1VZ//2Q==","aspectRatio":1,"src":"/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg","srcSet":"/static/b0de6281fb28a266510b3b09b9243e5a/f340b/Perfil.jpg 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/22d64/Perfil.jpg 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/31709/Perfil.jpg 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/aa249/Perfil.jpg 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/0dc33/Perfil.jpg 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/60667/Perfil.jpg 307w","srcWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp","srcSetWebp":"/static/b0de6281fb28a266510b3b09b9243e5a/59cda/Perfil.webp 28w,\n/static/b0de6281fb28a266510b3b09b9243e5a/7da75/Perfil.webp 55w,\n/static/b0de6281fb28a266510b3b09b9243e5a/8678c/Perfil.webp 110w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f282e/Perfil.webp 165w,\n/static/b0de6281fb28a266510b3b09b9243e5a/a7b21/Perfil.webp 220w,\n/static/b0de6281fb28a266510b3b09b9243e5a/f59af/Perfil.webp 307w","sizes":"(max-width: 110px) 100vw, 110px"}}}},"primary_tag":{"slug":"go","url":"https://jlgarcia.fulldev.ninja/tag/go/","name":"Go","visibility":"public","feature_image":null,"description":null,"meta_title":"Golang Ninjas","meta_description":"Aprenderemos a usar el nuevo lenguaje de Google para backend desde lo más básico a temas avanzados como concurrencia o api rest.","featureImageSharp":null},"tags":[{"slug":"go","url":"https://jlgarcia.fulldev.ninja/tag/go/","name":"Go","visibility":"public","feature_image":null,"description":null,"meta_title":"Golang Ninjas","meta_description":"Aprenderemos a usar el nuevo lenguaje de Google para backend desde lo más básico a temas avanzados como concurrencia o api rest.","featureImageSharp":null},{"slug":"golang","url":"https://jlgarcia.fulldev.ninja/tag/golang/","name":"Golang","visibility":"public","feature_image":null,"description":null,"meta_title":"Golang Ninjas","meta_description":"Aprenderemos a usar el nuevo lenguaje de Google para backend desde lo más básico a temas avanzados como concurrencia o api rest.","featureImageSharp":null}],"plaintext":"En Go tenemos dos tipos de arrays o arreglos:\n\n * Los que llaman arrays, son arreglos con una cantidad definida de elementos,es\n   decir, tienen un tamaño fijo y no pueden crecer.\n   \n   \n * Los llamados slices, que son los arreglos o arrays más comunes, en los cuales\n   podemos añadir los elementos que queramos.\n   \n   \n\nY porque tenemos dos tipos? Pues básicamente es por el consumo de recursos, los \narrays definidos, solo se reservan los recursos que necesitan, los slices o\nllamemoslos arrays dinámicos tienen siempre reservado una cantidad mayor de\nrecursos para poder crecer. Más abajo veremos como saber esta cantidad.\n\nArrays definidos\nLa forma de declararlos es bastante sencilla:\n\n//supongamos que son 3\nvar rangers [3]string\nrangers[0] = \"Ranger Rojo\"\nrangers[1] = \"Ranger Negro\"\nrangers[2] = \"Ranger Amarillo\"\n\n//El uso es como todos los arrays\nfmt.Println(rangers)\nfmt.Println(rangers[0])\nfmt.Println(rangers[1])\nfmt.Println(rangers[2])\n\n\nSi ejecutamos esto:\n\n\nHasta aqui todo parece normal, vamos a intentar añadir alguno mas:\n\nrangers[3] = \"Ranger Verde\"\n\n\nVemos como el propio visual studio nos avisa:\n\nLa única forma que tendriamos de ampliar ese array, o más bien de trabajar con\nlos datos que contiene, es hacer una copia del array en otro con más cantidad de\nelementos posibles(o que fuera un slice).\n\nMás abajo veremos como hacer eso, ya que es común para ambos tipos de array.\n\nSLICES\nContinuemos con los slices, que serán posiblemente el tipo más usado, sobretodo\nal principio.\nTenemos varias formas de crear slices, cada una tiene sus peculiaridades.\nLa primera:\n\nvar rangers []string\n\nrangers[0] = \"Ranger Rosa\"\nfmt.Println(rangers)\n\n\nEn un principio todo parece normal, el compilador no se queja tampoco, cool,\npero vamos a ejecutarlo:\n\nComo veis tenemos un bonito Panic (para el que no se lo imagine es como muestra\nlos errores) pero ¿porque?\n\nGo al inicializar los slices si lo hacemos de esa forma los inicializa por\ndefecto \"vacios\" pero no entendamos vacios como cualquier otro elemento que\npodemos asignarle un valor directamente, si no lo inicializa con \"ausencia de\ntodo\" incluso de tamaño.\nPero esto no significa que no podamos usarlo, Go tiene un método append que nos\npermite añadir los elementos que necesitemos:\n\nrangers = append(rangers, \"Ranger Rosa\", \"Ranger Rojo\")\n\nfmt.Println(rangers)\n\n\nPodriamos añadir todos los que queramos, y como vemos funciona perfectamente:\n\n\nAntes de continuar con la siguiente forma de inicializar slices vamos a hablar\nde \"Tamaño\" y \"Capacidad\"\n\n¿¿??\n\nSi jejejeje, con los slices en aplicaciones complejas tendremos que tener en\ncuenta estas dos cosas, pensando en la optimización por supuesto.\n\n * Tamaño: Básicamente es el tamaño que tiene ocupado el slice, lo que en otros\n   lenguajes consultaríamos con un array.length\n   \n   \n * Capacidad: Es la cantidad de recursos reservada para ese slice.\n   \n   \n\nEs decir si pensamos en los slices como cajas, tenemos que un slice con una\ncapacidad de 5 son 5 cajas, de las cuales 2 estan cerradas con algo\ndentro(tamaño 2) y otras 3 estan abiertas a la espera de tener algo dentro, pero\nestan ocupando su espacio en el suelo ya.\n\nAhora veamos la segunda forma de crear un slice:\n\nrangers := make([]string,10)\n//Aqui tendriamos un slice con 10 de tamaño y 10 de capacidad\n\nrangers := make([]string,5,10)\n//Y aqui tendriamos un slice con 5 de tamaño y 10 de capacidad\n\n\nVeamos un ejemplo de código para ilustrar un poco mejor esto:\n\nvar rangers []string\nfmt.Println(\"Sin inicializar, es decir tamaño 0\")\nfmt.Println(rangers)\n\nrangers = append(rangers, \"Ranger Rosa\", \"Ranger Rojo\")\n\nfmt.Println(\"Append al no inicializado\")\nfmt.Println(rangers)\n\nrangers2 := make([]string, 10)\n\nfmt.Println(\"Usando make para asignar tamaño y capacidad iguales\")\nfmt.Println(rangers2)\n\nrangers3 := make([]string, 5, 10)\n\nfmt.Println(\"Usando make para asignar tamaño y capacidad distintos\")\nfmt.Println(rangers3)\n\n\nSi ejecutamos este código tendriamos un resultado como este:\n\nSi os fijais tenemos bastantes diferencias en cuanto a la inicialización por\ndefecto de cada uno de los slices, el primero realmente tendria un valor similar\na null, en el segundo hemos inicializado ese null con dos elementos, en el \ntercero se ha aplicado la inicialización por defecto de go de strings(es decir\n\"\") sobre 10 elementos, en el ultimo esa misma inicialización sobre 5.\n\nAhora ya podemos usar lo que llamariamos asignación directa:\n\nrangers2[2] = \"Ranger Verde\"\nrangers3[3] = \"Ranger Negro\"\n\nfmt.Println(rangers2)\nfmt.Println(rangers3)\n\n\n\n\nBien hemos comprobado que podemos añadir ahora por lo menos dentro del \"tamaño\ninicializado\", si nos fijamos cada elemento tiene una posición definida dentro\ndel slice. Veamos ahora lo que pasa si intentamos añadir en una ubicación por\nencima del tamaño(ojo no de la capacidad). Lo vamos a intentar on ranger3 que\ntiene una capacidad de 10 y un tamaño de 5:\n\n\nVemos como nos vuelve a dar el error de que nos hemos salido del rango\npermitido. Para añadir por encima de esto tenemos que usar el mismo método que\nantes con append\n\nrangers3 = append(rangers3, \"Ranger Rosa\", \"Ranger Rojo\")\nfmt.Println(rangers3)\n\n\nSi ahora ejecutamos veremos como despues del espacio que teniamos antes ha\nañadido los dos rangers nuevos.\n\nOJO a lo de los espacios vamos a ver una ultima forma de inicializar Arrays y \nSlices y volveremos a este ejemplo para ver cosas sobre la capacidad y el tamaño\n.\n\nComo última forma vamos a ver la inicialización directa de ambos casos:\n\n//Array definido\nrangers2 := [2]string{\"Ranger Verde\", \"Ranger Blanco\"}\n//Slice\nrangers3 := []string{\"Ranger Rosa\", \"Ranger Amarillo\"}\n\t\nfmt.Println(rangers2)\t\nfmt.Println(rangers3)\n\n\nComo tal no notamos ninguna diferencia a la hora de mostrarlos:\n\n\nAtención si hacemos esto:\n\nrangers2 := [3]string{\"Ranger Verde\", \"Ranger Blanco\"}\n\n\nNos añade,en este caso un string(podria ser cualquier tipo que hubieramos\nindicado) vacio en el elemento faltante.\n\nBien ahora vamos a probar a añadir:\n\nrangers2 := [2]string{\"Ranger Verde\", \"Ranger Blanco\"}\nrangers3 := []string{\"Ranger Rosa\", \"Ranger Amarillo\"}\n\nrangers2 = append(rangers2, \"Ranger Negro\")\nrangers3 = append(rangers3, \"Ranger Blanco\")\n\n\nSi vemos el array definido se queja:\n\n\nComo tal sigue restringiendo su ampliación, lo contrario que el slice.\nAhora vamos a ver la diferencia real entre uno y otro.\n\nLen y Cap\nGo tiene como casi todos los lenguajes una forma de comprobar la cantidad de\nelementos que tiene un array,normalmente suele tener que ver con length, pues Go\nno iba a ser menos tenemos nuestro len:\n\nrangers3 := []string{\"Ranger Rosa\", \"Ranger Amarillo\"}\n\nfmt.Println(len(rangers3))\n\n\nEsto nos devuelve un 2, cosa normal no?? Pero como tal antes hemos hablado de la \ncapacidad también, en este caso Go tiene también una forma de ver la capacidad\nque tenemos reservada(básicamente es reserva en memoria)\n\nrangers3 := []string{\"Ranger Rosa\", \"Ranger Amarillo\"}\n\nfmt.Println(\"Tamaño\",len(rangers3))\nfmt.Println(\"Capacidad\",cap(rangers3))\n\n\nEsto nos devolveria:\n\n\nHasta aqui todo normal no?? Todo tiene sentido verdad?? Vale ahora vamos a\nañadirle algo para aumentarlo, recordemos que con capacidad 2 no podemos usar\nasignación directa para los siguientes elementos como tal tenemos que usar \nappend, vamos a usar append y veamos que nos devuelve ahora:\n\nrangers3 := []string{\"Ranger Rosa\", \"Ranger Amarillo\"}\n\nrangers3 = append(rangers3, \"Ranger Blanco\")\n\nfmt.Println(\"Tamaño\", len(rangers3))\nfmt.Println(\"Capacidad\", cap(rangers3))\n\n\nPara nuestra sorpresa al ejecutar vemos esto:\n\nUPS!!! y que ha pasaaaaaooooo!!!????, es simple Go lo que hace es duplicar la\ncapacidad anterior, por lo que si no tenemos en cuenta y tratamos con slices muy\ngrandes, por ejemplo imaginemos un array de 100 elementos, si añadimos 1 mas\npara hacer 101 tendriamos una capacidad de 200 siendo realmente inecesario.\nVeamoslo con un ejemplo añadiendo al código anterior los 2 rangers restantes:\n\nrangers3 := []string{\"Ranger Rosa\", \"Ranger Amarillo\"}\n\nrangers3 = append(rangers3, \"Ranger Blanco\")\n\nfmt.Println(\"Tamaño\", len(rangers3))\nfmt.Println(\"Capacidad\", cap(rangers3))\n\nrangers3 = append(rangers3, \"Ranger Rojo\", \"Ranger Negro\")\n\nfmt.Println(\"Tamaño\", len(rangers3))\nfmt.Println(\"Capacidad\", cap(rangers3))\n\n\nVemos que tenemos de repente una capacidad de 8:\n\n\nCreo que con esto mas o menos queda clara la diferencia entre los arrays\ndefinidos y los slices, hablando de consumo de memoria y del propio uso de uno u\notro, siempre sera recomendable tener arrays definidos, veremos más adelante\nalguna forma de pasar de uno a otro.\n\nEn el próximo post veremos tambien como trabajar con ambos, para recorrerlos,\npor ejemplo, y varias cosas mas.","html":"<!--kg-card-begin: markdown--><p>En Go tenemos dos tipos de <strong>arrays</strong> o <strong>arreglos</strong>:</p>\n<ul>\n<li>\n<p>Los que llaman <strong>arrays</strong>, son arreglos con una cantidad definida de elementos,es decir, tienen un tamaño fijo y no pueden crecer.</p>\n</li>\n<li>\n<p>Los llamados <strong>slices</strong>, que son los arreglos o arrays más comunes, en los cuales podemos añadir los elementos que queramos.</p>\n</li>\n</ul>\n<p>Y porque tenemos dos tipos? Pues básicamente es por el consumo de recursos, los <strong>arrays definidos</strong>, solo se reservan los recursos que necesitan, los <strong>slices</strong> o llamemoslos <strong>arrays dinámicos</strong> tienen siempre reservado una cantidad mayor de recursos para poder crecer. Más abajo veremos como saber esta cantidad.</p>\n<h2 id=\"arraysdefinidos\">Arrays definidos</h2>\n<p>La forma de declararlos es bastante sencilla:</p>\n<pre><code>//supongamos que son 3\nvar rangers [3]string\nrangers[0] = &quot;Ranger Rojo&quot;\nrangers[1] = &quot;Ranger Negro&quot;\nrangers[2] = &quot;Ranger Amarillo&quot;\n\n//El uso es como todos los arrays\nfmt.Println(rangers)\nfmt.Println(rangers[0])\nfmt.Println(rangers[1])\nfmt.Println(rangers[2])\n</code></pre>\n<p>Si ejecutamos esto:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen0814.png\" alt=\"\"></p>\n<p>Hasta aqui todo parece normal, vamos a intentar añadir alguno mas:</p>\n<pre><code>rangers[3] = &quot;Ranger Verde&quot;\n</code></pre>\n<p>Vemos como el propio visual studio nos avisa:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen0831.png\" alt=\"\"><br>\nLa única forma que tendriamos de ampliar ese array, o más bien de trabajar con los datos que contiene, es hacer una copia del array en otro con más cantidad de elementos posibles(o que fuera un <strong>slice</strong>).</p>\n<p>Más abajo veremos como hacer eso, ya que es común para ambos tipos de array.</p>\n<h2 id=\"slices\">SLICES</h2>\n<p>Continuemos con los <strong>slices</strong>, que serán posiblemente el tipo más usado, sobretodo al principio.<br>\nTenemos varias formas de crear <strong>slices</strong>, cada una tiene sus peculiaridades.<br>\nLa primera:</p>\n<pre><code>var rangers []string\n\nrangers[0] = &quot;Ranger Rosa&quot;\nfmt.Println(rangers)\n</code></pre>\n<p>En un principio todo parece normal, el compilador no se queja tampoco, <em>cool</em>, pero vamos a ejecutarlo:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen08.45.05.png\" alt=\"\"><br>\nComo veis tenemos un bonito <span style=\"color:red\">Panic</span> (para el que no se lo imagine es como muestra los errores) pero ¿porque?</p>\n<p>Go al inicializar los <strong>slices</strong> si lo hacemos de esa forma los inicializa por defecto <strong>&quot;vacios&quot;</strong> pero no entendamos vacios como cualquier otro elemento que podemos asignarle un valor directamente, si no lo inicializa con <strong>&quot;ausencia de todo&quot;</strong> incluso de tamaño.<br>\nPero esto no significa que no podamos usarlo, Go tiene un método <strong>append</strong> que nos permite añadir los elementos que necesitemos:</p>\n<pre><code>rangers = append(rangers, &quot;Ranger Rosa&quot;, &quot;Ranger Rojo&quot;)\n\nfmt.Println(rangers)\n</code></pre>\n<p>Podriamos añadir todos los que queramos, y como vemos funciona perfectamente:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen08.57.07.png\" alt=\"\"></p>\n<p>Antes de continuar con la siguiente forma de inicializar <strong>slices</strong> vamos a hablar de <strong>&quot;Tamaño&quot;</strong> y <strong>&quot;Capacidad&quot;</strong></p>\n<p>¿¿??</p>\n<p>Si jejejeje, con los slices en aplicaciones complejas tendremos que tener en cuenta estas dos cosas, pensando en la optimización por supuesto.</p>\n<ul>\n<li>\n<p><strong>Tamaño</strong>: Básicamente es el tamaño que tiene ocupado el slice, lo que en otros lenguajes consultaríamos con un <strong>array.length</strong></p>\n</li>\n<li>\n<p><strong>Capacidad</strong>: Es la cantidad de recursos reservada para ese <strong>slice</strong>.</p>\n</li>\n</ul>\n<p>Es decir si pensamos en los slices como cajas, tenemos que un slice con una capacidad de 5 son 5 cajas, de las cuales 2 estan cerradas con algo dentro(tamaño 2) y otras 3 estan abiertas a la espera de tener algo dentro, pero estan ocupando su espacio en el suelo ya.</p>\n<p>Ahora veamos la segunda forma de crear un <strong>slice</strong>:</p>\n<pre><code>rangers := make([]string,10)\n//Aqui tendriamos un slice con 10 de tamaño y 10 de capacidad\n\nrangers := make([]string,5,10)\n//Y aqui tendriamos un slice con 5 de tamaño y 10 de capacidad\n</code></pre>\n<p>Veamos un ejemplo de código para ilustrar un poco mejor esto:</p>\n<pre><code>var rangers []string\nfmt.Println(&quot;Sin inicializar, es decir tamaño 0&quot;)\nfmt.Println(rangers)\n\nrangers = append(rangers, &quot;Ranger Rosa&quot;, &quot;Ranger Rojo&quot;)\n\nfmt.Println(&quot;Append al no inicializado&quot;)\nfmt.Println(rangers)\n\nrangers2 := make([]string, 10)\n\nfmt.Println(&quot;Usando make para asignar tamaño y capacidad iguales&quot;)\nfmt.Println(rangers2)\n\nrangers3 := make([]string, 5, 10)\n\nfmt.Println(&quot;Usando make para asignar tamaño y capacidad distintos&quot;)\nfmt.Println(rangers3)\n</code></pre>\n<p>Si ejecutamos este código tendriamos un resultado como este:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen09.30.55.png\" alt=\"\"><br>\nSi os fijais tenemos bastantes diferencias en cuanto a la inicialización por defecto de cada uno de los slices, el <strong>primero</strong> realmente tendria un valor similar a <strong>null</strong>, en el <strong>segundo</strong> hemos inicializado ese null con dos elementos, en el <strong>tercero</strong> se ha aplicado la inicialización por defecto de go de strings(es decir &quot;&quot;) sobre 10 elementos, en el <strong>ultimo</strong> esa misma inicialización sobre 5.</p>\n<p>Ahora ya podemos usar lo que llamariamos asignación directa:</p>\n<pre><code>rangers2[2] = &quot;Ranger Verde&quot;\nrangers3[3] = &quot;Ranger Negro&quot;\n\nfmt.Println(rangers2)\nfmt.Println(rangers3)\n</code></pre>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen20.56.57.png\" alt=\"\"></p>\n<p>Bien hemos comprobado que podemos añadir ahora por lo menos dentro del &quot;tamaño inicializado&quot;, si nos fijamos cada elemento tiene una posición definida dentro del slice. Veamos ahora lo que pasa si intentamos añadir en una ubicación por encima del <strong>tamaño</strong>(ojo no de la capacidad). Lo vamos a intentar on <strong>ranger3</strong> que tiene una capacidad de 10 y un tamaño de 5:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen21.00.34.png\" alt=\"\"></p>\n<p>Vemos como nos vuelve a dar el error de que nos hemos salido del rango permitido. Para añadir por encima de esto tenemos que usar el mismo método que antes con <strong>append</strong></p>\n<pre><code>rangers3 = append(rangers3, &quot;Ranger Rosa&quot;, &quot;Ranger Rojo&quot;)\nfmt.Println(rangers3)\n</code></pre>\n<p>Si ahora ejecutamos veremos como despues del espacio que teniamos antes ha añadido los dos rangers nuevos.<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen21.06.25.png\" alt=\"\"><br>\n<strong>OJO a lo de los espacios</strong> vamos a ver una ultima forma de inicializar <strong>Arrays</strong> y <strong>Slices</strong> y volveremos a este ejemplo para ver cosas sobre la <strong>capacidad</strong> y el <strong>tamaño</strong>.</p>\n<p>Como última forma vamos a ver la inicialización directa de ambos casos:</p>\n<pre><code>//Array definido\nrangers2 := [2]string{&quot;Ranger Verde&quot;, &quot;Ranger Blanco&quot;}\n//Slice\nrangers3 := []string{&quot;Ranger Rosa&quot;, &quot;Ranger Amarillo&quot;}\n\t\nfmt.Println(rangers2)\t\nfmt.Println(rangers3)\n</code></pre>\n<p>Como tal no notamos ninguna diferencia a la hora de mostrarlos:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen21.17.55.png\" alt=\"\"></p>\n<p><strong>Atención</strong> si hacemos esto:</p>\n<pre><code>rangers2 := [3]string{&quot;Ranger Verde&quot;, &quot;Ranger Blanco&quot;}\n</code></pre>\n<p>Nos añade,en este caso un string(podria ser cualquier tipo que hubieramos indicado) vacio en el elemento faltante.</p>\n<p>Bien ahora vamos a probar a añadir:</p>\n<pre><code>rangers2 := [2]string{&quot;Ranger Verde&quot;, &quot;Ranger Blanco&quot;}\nrangers3 := []string{&quot;Ranger Rosa&quot;, &quot;Ranger Amarillo&quot;}\n\nrangers2 = append(rangers2, &quot;Ranger Negro&quot;)\nrangers3 = append(rangers3, &quot;Ranger Blanco&quot;)\n</code></pre>\n<p>Si vemos el <strong>array definido</strong> se queja:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen21.20.36.png\" alt=\"\"></p>\n<p>Como tal sigue restringiendo su ampliación, lo contrario que el <strong>slice</strong>.<br>\nAhora vamos a ver la diferencia real entre uno y otro.</p>\n<h2 id=\"lenycap\">Len y Cap</h2>\n<p>Go tiene como casi todos los lenguajes una forma de comprobar la cantidad de elementos que tiene un array,normalmente suele tener que ver con <strong>length</strong>, pues Go no iba a ser menos tenemos nuestro len:</p>\n<pre><code>rangers3 := []string{&quot;Ranger Rosa&quot;, &quot;Ranger Amarillo&quot;}\n\nfmt.Println(len(rangers3))\n</code></pre>\n<p>Esto nos devuelve un 2, cosa normal no?? Pero como tal antes hemos hablado de la <strong>capacidad</strong> también, en este caso Go tiene también una forma de ver la capacidad que tenemos reservada(básicamente es reserva en memoria)</p>\n<pre><code>rangers3 := []string{&quot;Ranger Rosa&quot;, &quot;Ranger Amarillo&quot;}\n\nfmt.Println(&quot;Tamaño&quot;,len(rangers3))\nfmt.Println(&quot;Capacidad&quot;,cap(rangers3))\n</code></pre>\n<p>Esto nos devolveria:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen21.31.12.png\" alt=\"\"></p>\n<p>Hasta aqui todo normal no?? Todo tiene sentido verdad?? Vale ahora vamos a añadirle algo para aumentarlo, recordemos que con <strong>capacidad 2</strong> no podemos usar asignación directa para los siguientes elementos como tal tenemos que usar <strong>append</strong>, vamos a usar <strong>append</strong> y veamos que nos devuelve ahora:</p>\n<pre><code>rangers3 := []string{&quot;Ranger Rosa&quot;, &quot;Ranger Amarillo&quot;}\n\nrangers3 = append(rangers3, &quot;Ranger Blanco&quot;)\n\nfmt.Println(&quot;Tamaño&quot;, len(rangers3))\nfmt.Println(&quot;Capacidad&quot;, cap(rangers3))\n</code></pre>\n<p>Para nuestra sorpresa al ejecutar vemos esto:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen21.34.02.png\" alt=\"\"><br>\n<strong>UPS!!!</strong> <em>y que ha pasaaaaaooooo!!!????</em>, es simple Go lo que hace es duplicar la capacidad anterior, por lo que si no tenemos en cuenta y tratamos con slices muy grandes, por ejemplo imaginemos un array de 100 elementos, si añadimos 1 mas para hacer 101 tendriamos una capacidad de 200 siendo realmente inecesario.<br>\nVeamoslo con un ejemplo añadiendo al código anterior los 2 rangers restantes:</p>\n<pre><code>rangers3 := []string{&quot;Ranger Rosa&quot;, &quot;Ranger Amarillo&quot;}\n\nrangers3 = append(rangers3, &quot;Ranger Blanco&quot;)\n\nfmt.Println(&quot;Tamaño&quot;, len(rangers3))\nfmt.Println(&quot;Capacidad&quot;, cap(rangers3))\n\nrangers3 = append(rangers3, &quot;Ranger Rojo&quot;, &quot;Ranger Negro&quot;)\n\nfmt.Println(&quot;Tamaño&quot;, len(rangers3))\nfmt.Println(&quot;Capacidad&quot;, cap(rangers3))\n</code></pre>\n<p>Vemos que tenemos de repente una capacidad de 8:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen21.39.27.png\" alt=\"\"></p>\n<p>Creo que con esto mas o menos queda clara la diferencia entre los arrays definidos y los slices, hablando de consumo de memoria y del propio uso de uno u otro, siempre sera recomendable tener arrays definidos, veremos más adelante alguna forma de pasar de uno a otro.</p>\n<p>En el próximo post veremos tambien como trabajar con ambos, para recorrerlos, por ejemplo, y varias cosas mas.</p>\n<!--kg-card-end: markdown-->","url":"https://jlgarcia.fulldev.ninja/go-go-power-ra-ah-que-no-go-parte-3-arrays-y-slices-i/","canonical_url":null,"uuid":"35e1d966-d22e-4a90-8c8c-8c46b92de7e1","codeinjection_foot":null,"codeinjection_head":null,"codeinjection_styles":null,"comment_id":"24","reading_time":7,"send_email_when_published":false,"email_subject":null,"childHtmlRehype":{"html":"<!--kg-card-begin: markdown--><p>En Go tenemos dos tipos de <strong>arrays</strong> o <strong>arreglos</strong>:</p>\n<ul>\n<li>\n<p>Los que llaman <strong>arrays</strong>, son arreglos con una cantidad definida de elementos,es decir, tienen un tamaño fijo y no pueden crecer.</p>\n</li>\n<li>\n<p>Los llamados <strong>slices</strong>, que son los arreglos o arrays más comunes, en los cuales podemos añadir los elementos que queramos.</p>\n</li>\n</ul>\n<p>Y porque tenemos dos tipos? Pues básicamente es por el consumo de recursos, los <strong>arrays definidos</strong>, solo se reservan los recursos que necesitan, los <strong>slices</strong> o llamemoslos <strong>arrays dinámicos</strong> tienen siempre reservado una cantidad mayor de recursos para poder crecer. Más abajo veremos como saber esta cantidad.</p>\n<h2 id=\"arraysdefinidos\">Arrays definidos</h2>\n<p>La forma de declararlos es bastante sencilla:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">//supongamos que son 3\nvar rangers [3]string\nrangers[0] = \"Ranger Rojo\"\nrangers[1] = \"Ranger Negro\"\nrangers[2] = \"Ranger Amarillo\"\n\n//El uso es como todos los arrays\nfmt.Println(rangers)\nfmt.Println(rangers[0])\nfmt.Println(rangers[1])\nfmt.Println(rangers[2])\n</code></pre></div>\n<p>Si ejecutamos esto:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen0814.png\" alt=\"\"></p>\n<p>Hasta aqui todo parece normal, vamos a intentar añadir alguno mas:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">rangers[3] = \"Ranger Verde\"\n</code></pre></div>\n<p>Vemos como el propio visual studio nos avisa:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen0831.png\" alt=\"\"><br>\nLa única forma que tendriamos de ampliar ese array, o más bien de trabajar con los datos que contiene, es hacer una copia del array en otro con más cantidad de elementos posibles(o que fuera un <strong>slice</strong>).</p>\n<p>Más abajo veremos como hacer eso, ya que es común para ambos tipos de array.</p>\n<h2 id=\"slices\">SLICES</h2>\n<p>Continuemos con los <strong>slices</strong>, que serán posiblemente el tipo más usado, sobretodo al principio.<br>\nTenemos varias formas de crear <strong>slices</strong>, cada una tiene sus peculiaridades.<br>\nLa primera:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">var rangers []string\n\nrangers[0] = \"Ranger Rosa\"\nfmt.Println(rangers)\n</code></pre></div>\n<p>En un principio todo parece normal, el compilador no se queja tampoco, <em>cool</em>, pero vamos a ejecutarlo:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen08.45.05.png\" alt=\"\"><br>\nComo veis tenemos un bonito <span style=\"color:red\">Panic</span> (para el que no se lo imagine es como muestra los errores) pero ¿porque?</p>\n<p>Go al inicializar los <strong>slices</strong> si lo hacemos de esa forma los inicializa por defecto <strong>\"vacios\"</strong> pero no entendamos vacios como cualquier otro elemento que podemos asignarle un valor directamente, si no lo inicializa con <strong>\"ausencia de todo\"</strong> incluso de tamaño.<br>\nPero esto no significa que no podamos usarlo, Go tiene un método <strong>append</strong> que nos permite añadir los elementos que necesitemos:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">rangers = append(rangers, \"Ranger Rosa\", \"Ranger Rojo\")\n\nfmt.Println(rangers)\n</code></pre></div>\n<p>Podriamos añadir todos los que queramos, y como vemos funciona perfectamente:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen08.57.07.png\" alt=\"\"></p>\n<p>Antes de continuar con la siguiente forma de inicializar <strong>slices</strong> vamos a hablar de <strong>\"Tamaño\"</strong> y <strong>\"Capacidad\"</strong></p>\n<p>¿¿??</p>\n<p>Si jejejeje, con los slices en aplicaciones complejas tendremos que tener en cuenta estas dos cosas, pensando en la optimización por supuesto.</p>\n<ul>\n<li>\n<p><strong>Tamaño</strong>: Básicamente es el tamaño que tiene ocupado el slice, lo que en otros lenguajes consultaríamos con un <strong>array.length</strong></p>\n</li>\n<li>\n<p><strong>Capacidad</strong>: Es la cantidad de recursos reservada para ese <strong>slice</strong>.</p>\n</li>\n</ul>\n<p>Es decir si pensamos en los slices como cajas, tenemos que un slice con una capacidad de 5 son 5 cajas, de las cuales 2 estan cerradas con algo dentro(tamaño 2) y otras 3 estan abiertas a la espera de tener algo dentro, pero estan ocupando su espacio en el suelo ya.</p>\n<p>Ahora veamos la segunda forma de crear un <strong>slice</strong>:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">rangers := make([]string,10)\n//Aqui tendriamos un slice con 10 de tamaño y 10 de capacidad\n\nrangers := make([]string,5,10)\n//Y aqui tendriamos un slice con 5 de tamaño y 10 de capacidad\n</code></pre></div>\n<p>Veamos un ejemplo de código para ilustrar un poco mejor esto:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">var rangers []string\nfmt.Println(\"Sin inicializar, es decir tamaño 0\")\nfmt.Println(rangers)\n\nrangers = append(rangers, \"Ranger Rosa\", \"Ranger Rojo\")\n\nfmt.Println(\"Append al no inicializado\")\nfmt.Println(rangers)\n\nrangers2 := make([]string, 10)\n\nfmt.Println(\"Usando make para asignar tamaño y capacidad iguales\")\nfmt.Println(rangers2)\n\nrangers3 := make([]string, 5, 10)\n\nfmt.Println(\"Usando make para asignar tamaño y capacidad distintos\")\nfmt.Println(rangers3)\n</code></pre></div>\n<p>Si ejecutamos este código tendriamos un resultado como este:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen09.30.55.png\" alt=\"\"><br>\nSi os fijais tenemos bastantes diferencias en cuanto a la inicialización por defecto de cada uno de los slices, el <strong>primero</strong> realmente tendria un valor similar a <strong>null</strong>, en el <strong>segundo</strong> hemos inicializado ese null con dos elementos, en el <strong>tercero</strong> se ha aplicado la inicialización por defecto de go de strings(es decir \"\") sobre 10 elementos, en el <strong>ultimo</strong> esa misma inicialización sobre 5.</p>\n<p>Ahora ya podemos usar lo que llamariamos asignación directa:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">rangers2[2] = \"Ranger Verde\"\nrangers3[3] = \"Ranger Negro\"\n\nfmt.Println(rangers2)\nfmt.Println(rangers3)\n</code></pre></div>\n<p><img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen20.56.57.png\" alt=\"\"></p>\n<p>Bien hemos comprobado que podemos añadir ahora por lo menos dentro del \"tamaño inicializado\", si nos fijamos cada elemento tiene una posición definida dentro del slice. Veamos ahora lo que pasa si intentamos añadir en una ubicación por encima del <strong>tamaño</strong>(ojo no de la capacidad). Lo vamos a intentar on <strong>ranger3</strong> que tiene una capacidad de 10 y un tamaño de 5:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen21.00.34.png\" alt=\"\"></p>\n<p>Vemos como nos vuelve a dar el error de que nos hemos salido del rango permitido. Para añadir por encima de esto tenemos que usar el mismo método que antes con <strong>append</strong></p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">rangers3 = append(rangers3, \"Ranger Rosa\", \"Ranger Rojo\")\nfmt.Println(rangers3)\n</code></pre></div>\n<p>Si ahora ejecutamos veremos como despues del espacio que teniamos antes ha añadido los dos rangers nuevos.<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen21.06.25.png\" alt=\"\"><br>\n<strong>OJO a lo de los espacios</strong> vamos a ver una ultima forma de inicializar <strong>Arrays</strong> y <strong>Slices</strong> y volveremos a este ejemplo para ver cosas sobre la <strong>capacidad</strong> y el <strong>tamaño</strong>.</p>\n<p>Como última forma vamos a ver la inicialización directa de ambos casos:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">//Array definido\nrangers2 := [2]string{\"Ranger Verde\", \"Ranger Blanco\"}\n//Slice\nrangers3 := []string{\"Ranger Rosa\", \"Ranger Amarillo\"}\n\t\nfmt.Println(rangers2)\t\nfmt.Println(rangers3)\n</code></pre></div>\n<p>Como tal no notamos ninguna diferencia a la hora de mostrarlos:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen21.17.55.png\" alt=\"\"></p>\n<p><strong>Atención</strong> si hacemos esto:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">rangers2 := [3]string{\"Ranger Verde\", \"Ranger Blanco\"}\n</code></pre></div>\n<p>Nos añade,en este caso un string(podria ser cualquier tipo que hubieramos indicado) vacio en el elemento faltante.</p>\n<p>Bien ahora vamos a probar a añadir:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">rangers2 := [2]string{\"Ranger Verde\", \"Ranger Blanco\"}\nrangers3 := []string{\"Ranger Rosa\", \"Ranger Amarillo\"}\n\nrangers2 = append(rangers2, \"Ranger Negro\")\nrangers3 = append(rangers3, \"Ranger Blanco\")\n</code></pre></div>\n<p>Si vemos el <strong>array definido</strong> se queja:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen21.20.36.png\" alt=\"\"></p>\n<p>Como tal sigue restringiendo su ampliación, lo contrario que el <strong>slice</strong>.<br>\nAhora vamos a ver la diferencia real entre uno y otro.</p>\n<h2 id=\"lenycap\">Len y Cap</h2>\n<p>Go tiene como casi todos los lenguajes una forma de comprobar la cantidad de elementos que tiene un array,normalmente suele tener que ver con <strong>length</strong>, pues Go no iba a ser menos tenemos nuestro len:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">rangers3 := []string{\"Ranger Rosa\", \"Ranger Amarillo\"}\n\nfmt.Println(len(rangers3))\n</code></pre></div>\n<p>Esto nos devuelve un 2, cosa normal no?? Pero como tal antes hemos hablado de la <strong>capacidad</strong> también, en este caso Go tiene también una forma de ver la capacidad que tenemos reservada(básicamente es reserva en memoria)</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">rangers3 := []string{\"Ranger Rosa\", \"Ranger Amarillo\"}\n\nfmt.Println(\"Tamaño\",len(rangers3))\nfmt.Println(\"Capacidad\",cap(rangers3))\n</code></pre></div>\n<p>Esto nos devolveria:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen21.31.12.png\" alt=\"\"></p>\n<p>Hasta aqui todo normal no?? Todo tiene sentido verdad?? Vale ahora vamos a añadirle algo para aumentarlo, recordemos que con <strong>capacidad 2</strong> no podemos usar asignación directa para los siguientes elementos como tal tenemos que usar <strong>append</strong>, vamos a usar <strong>append</strong> y veamos que nos devuelve ahora:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">rangers3 := []string{\"Ranger Rosa\", \"Ranger Amarillo\"}\n\nrangers3 = append(rangers3, \"Ranger Blanco\")\n\nfmt.Println(\"Tamaño\", len(rangers3))\nfmt.Println(\"Capacidad\", cap(rangers3))\n</code></pre></div>\n<p>Para nuestra sorpresa al ejecutar vemos esto:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen21.34.02.png\" alt=\"\"><br>\n<strong>UPS!!!</strong> <em>y que ha pasaaaaaooooo!!!????</em>, es simple Go lo que hace es duplicar la capacidad anterior, por lo que si no tenemos en cuenta y tratamos con slices muy grandes, por ejemplo imaginemos un array de 100 elementos, si añadimos 1 mas para hacer 101 tendriamos una capacidad de 200 siendo realmente inecesario.<br>\nVeamoslo con un ejemplo añadiendo al código anterior los 2 rangers restantes:</p>\n<div class=\"kg-card kg-code-card gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">rangers3 := []string{\"Ranger Rosa\", \"Ranger Amarillo\"}\n\nrangers3 = append(rangers3, \"Ranger Blanco\")\n\nfmt.Println(\"Tamaño\", len(rangers3))\nfmt.Println(\"Capacidad\", cap(rangers3))\n\nrangers3 = append(rangers3, \"Ranger Rojo\", \"Ranger Negro\")\n\nfmt.Println(\"Tamaño\", len(rangers3))\nfmt.Println(\"Capacidad\", cap(rangers3))\n</code></pre></div>\n<p>Vemos que tenemos de repente una capacidad de 8:<br>\n<img src=\"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen21.39.27.png\" alt=\"\"></p>\n<p>Creo que con esto mas o menos queda clara la diferencia entre los arrays definidos y los slices, hablando de consumo de memoria y del propio uso de uno u otro, siempre sera recomendable tener arrays definidos, veremos más adelante alguna forma de pasar de uno a otro.</p>\n<p>En el próximo post veremos tambien como trabajar con ambos, para recorrerlos, por ejemplo, y varias cosas mas.</p>\n<!--kg-card-end: markdown-->","htmlAst":{"type":"root","children":[{"type":"comment","value":"kg-card-begin: markdown"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"En Go tenemos dos tipos de "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"arrays"}]},{"type":"text","value":" o "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"arreglos"}]},{"type":"text","value":":"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Los que llaman "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"arrays"}]},{"type":"text","value":", son arreglos con una cantidad definida de elementos,es decir, tienen un tamaño fijo y no pueden crecer."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Los llamados "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"slices"}]},{"type":"text","value":", que son los arreglos o arrays más comunes, en los cuales podemos añadir los elementos que queramos."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Y porque tenemos dos tipos? Pues básicamente es por el consumo de recursos, los "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"arrays definidos"}]},{"type":"text","value":", solo se reservan los recursos que necesitan, los "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"slices"}]},{"type":"text","value":" o llamemoslos "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"arrays dinámicos"}]},{"type":"text","value":" tienen siempre reservado una cantidad mayor de recursos para poder crecer. Más abajo veremos como saber esta cantidad."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"arraysdefinidos"},"children":[{"type":"text","value":"Arrays definidos"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"La forma de declararlos es bastante sencilla:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"//supongamos que son 3\nvar rangers [3]string\nrangers[0] = \"Ranger Rojo\"\nrangers[1] = \"Ranger Negro\"\nrangers[2] = \"Ranger Amarillo\"\n\n//El uso es como todos los arrays\nfmt.Println(rangers)\nfmt.Println(rangers[0])\nfmt.Println(rangers[1])\nfmt.Println(rangers[2])\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Si ejecutamos esto:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen0814.png","alt":""},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Hasta aqui todo parece normal, vamos a intentar añadir alguno mas:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"rangers[3] = \"Ranger Verde\"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Vemos como el propio visual studio nos avisa:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen0831.png","alt":""},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nLa única forma que tendriamos de ampliar ese array, o más bien de trabajar con los datos que contiene, es hacer una copia del array en otro con más cantidad de elementos posibles(o que fuera un "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"slice"}]},{"type":"text","value":")."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Más abajo veremos como hacer eso, ya que es común para ambos tipos de array."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"slices"},"children":[{"type":"text","value":"SLICES"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Continuemos con los "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"slices"}]},{"type":"text","value":", que serán posiblemente el tipo más usado, sobretodo al principio."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nTenemos varias formas de crear "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"slices"}]},{"type":"text","value":", cada una tiene sus peculiaridades."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nLa primera:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"var rangers []string\n\nrangers[0] = \"Ranger Rosa\"\nfmt.Println(rangers)\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"En un principio todo parece normal, el compilador no se queja tampoco, "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"cool"}]},{"type":"text","value":", pero vamos a ejecutarlo:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen08.45.05.png","alt":""},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nComo veis tenemos un bonito "},{"type":"element","tagName":"span","properties":{"style":"color:red"},"children":[{"type":"text","value":"Panic"}]},{"type":"text","value":" (para el que no se lo imagine es como muestra los errores) pero ¿porque?"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Go al inicializar los "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"slices"}]},{"type":"text","value":" si lo hacemos de esa forma los inicializa por defecto "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"\"vacios\""}]},{"type":"text","value":" pero no entendamos vacios como cualquier otro elemento que podemos asignarle un valor directamente, si no lo inicializa con "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"\"ausencia de todo\""}]},{"type":"text","value":" incluso de tamaño."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nPero esto no significa que no podamos usarlo, Go tiene un método "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"append"}]},{"type":"text","value":" que nos permite añadir los elementos que necesitemos:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"rangers = append(rangers, \"Ranger Rosa\", \"Ranger Rojo\")\n\nfmt.Println(rangers)\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Podriamos añadir todos los que queramos, y como vemos funciona perfectamente:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen08.57.07.png","alt":""},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Antes de continuar con la siguiente forma de inicializar "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"slices"}]},{"type":"text","value":" vamos a hablar de "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"\"Tamaño\""}]},{"type":"text","value":" y "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"\"Capacidad\""}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"¿¿??"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Si jejejeje, con los slices en aplicaciones complejas tendremos que tener en cuenta estas dos cosas, pensando en la optimización por supuesto."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Tamaño"}]},{"type":"text","value":": Básicamente es el tamaño que tiene ocupado el slice, lo que en otros lenguajes consultaríamos con un "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"array.length"}]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Capacidad"}]},{"type":"text","value":": Es la cantidad de recursos reservada para ese "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"slice"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Es decir si pensamos en los slices como cajas, tenemos que un slice con una capacidad de 5 son 5 cajas, de las cuales 2 estan cerradas con algo dentro(tamaño 2) y otras 3 estan abiertas a la espera de tener algo dentro, pero estan ocupando su espacio en el suelo ya."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Ahora veamos la segunda forma de crear un "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"slice"}]},{"type":"text","value":":"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"rangers := make([]string,10)\n//Aqui tendriamos un slice con 10 de tamaño y 10 de capacidad\n\nrangers := make([]string,5,10)\n//Y aqui tendriamos un slice con 5 de tamaño y 10 de capacidad\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Veamos un ejemplo de código para ilustrar un poco mejor esto:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"var rangers []string\nfmt.Println(\"Sin inicializar, es decir tamaño 0\")\nfmt.Println(rangers)\n\nrangers = append(rangers, \"Ranger Rosa\", \"Ranger Rojo\")\n\nfmt.Println(\"Append al no inicializado\")\nfmt.Println(rangers)\n\nrangers2 := make([]string, 10)\n\nfmt.Println(\"Usando make para asignar tamaño y capacidad iguales\")\nfmt.Println(rangers2)\n\nrangers3 := make([]string, 5, 10)\n\nfmt.Println(\"Usando make para asignar tamaño y capacidad distintos\")\nfmt.Println(rangers3)\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Si ejecutamos este código tendriamos un resultado como este:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen09.30.55.png","alt":""},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nSi os fijais tenemos bastantes diferencias en cuanto a la inicialización por defecto de cada uno de los slices, el "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"primero"}]},{"type":"text","value":" realmente tendria un valor similar a "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"null"}]},{"type":"text","value":", en el "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"segundo"}]},{"type":"text","value":" hemos inicializado ese null con dos elementos, en el "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"tercero"}]},{"type":"text","value":" se ha aplicado la inicialización por defecto de go de strings(es decir \"\") sobre 10 elementos, en el "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"ultimo"}]},{"type":"text","value":" esa misma inicialización sobre 5."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Ahora ya podemos usar lo que llamariamos asignación directa:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"rangers2[2] = \"Ranger Verde\"\nrangers3[3] = \"Ranger Negro\"\n\nfmt.Println(rangers2)\nfmt.Println(rangers3)\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen20.56.57.png","alt":""},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Bien hemos comprobado que podemos añadir ahora por lo menos dentro del \"tamaño inicializado\", si nos fijamos cada elemento tiene una posición definida dentro del slice. Veamos ahora lo que pasa si intentamos añadir en una ubicación por encima del "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"tamaño"}]},{"type":"text","value":"(ojo no de la capacidad). Lo vamos a intentar on "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"ranger3"}]},{"type":"text","value":" que tiene una capacidad de 10 y un tamaño de 5:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen21.00.34.png","alt":""},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Vemos como nos vuelve a dar el error de que nos hemos salido del rango permitido. Para añadir por encima de esto tenemos que usar el mismo método que antes con "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"append"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"rangers3 = append(rangers3, \"Ranger Rosa\", \"Ranger Rojo\")\nfmt.Println(rangers3)\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Si ahora ejecutamos veremos como despues del espacio que teniamos antes ha añadido los dos rangers nuevos."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen21.06.25.png","alt":""},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"OJO a lo de los espacios"}]},{"type":"text","value":" vamos a ver una ultima forma de inicializar "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Arrays"}]},{"type":"text","value":" y "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Slices"}]},{"type":"text","value":" y volveremos a este ejemplo para ver cosas sobre la "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"capacidad"}]},{"type":"text","value":" y el "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"tamaño"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Como última forma vamos a ver la inicialización directa de ambos casos:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"//Array definido\nrangers2 := [2]string{\"Ranger Verde\", \"Ranger Blanco\"}\n//Slice\nrangers3 := []string{\"Ranger Rosa\", \"Ranger Amarillo\"}\n\t\nfmt.Println(rangers2)\t\nfmt.Println(rangers3)\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Como tal no notamos ninguna diferencia a la hora de mostrarlos:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen21.17.55.png","alt":""},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Atención"}]},{"type":"text","value":" si hacemos esto:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"rangers2 := [3]string{\"Ranger Verde\", \"Ranger Blanco\"}\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Nos añade,en este caso un string(podria ser cualquier tipo que hubieramos indicado) vacio en el elemento faltante."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Bien ahora vamos a probar a añadir:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"rangers2 := [2]string{\"Ranger Verde\", \"Ranger Blanco\"}\nrangers3 := []string{\"Ranger Rosa\", \"Ranger Amarillo\"}\n\nrangers2 = append(rangers2, \"Ranger Negro\")\nrangers3 = append(rangers3, \"Ranger Blanco\")\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Si vemos el "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"array definido"}]},{"type":"text","value":" se queja:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen21.20.36.png","alt":""},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Como tal sigue restringiendo su ampliación, lo contrario que el "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"slice"}]},{"type":"text","value":"."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nAhora vamos a ver la diferencia real entre uno y otro."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"lenycap"},"children":[{"type":"text","value":"Len y Cap"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Go tiene como casi todos los lenguajes una forma de comprobar la cantidad de elementos que tiene un array,normalmente suele tener que ver con "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"length"}]},{"type":"text","value":", pues Go no iba a ser menos tenemos nuestro len:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"rangers3 := []string{\"Ranger Rosa\", \"Ranger Amarillo\"}\n\nfmt.Println(len(rangers3))\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Esto nos devuelve un 2, cosa normal no?? Pero como tal antes hemos hablado de la "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"capacidad"}]},{"type":"text","value":" también, en este caso Go tiene también una forma de ver la capacidad que tenemos reservada(básicamente es reserva en memoria)"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"rangers3 := []string{\"Ranger Rosa\", \"Ranger Amarillo\"}\n\nfmt.Println(\"Tamaño\",len(rangers3))\nfmt.Println(\"Capacidad\",cap(rangers3))\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Esto nos devolveria:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen21.31.12.png","alt":""},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Hasta aqui todo normal no?? Todo tiene sentido verdad?? Vale ahora vamos a añadirle algo para aumentarlo, recordemos que con "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"capacidad 2"}]},{"type":"text","value":" no podemos usar asignación directa para los siguientes elementos como tal tenemos que usar "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"append"}]},{"type":"text","value":", vamos a usar "},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"append"}]},{"type":"text","value":" y veamos que nos devuelve ahora:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"rangers3 := []string{\"Ranger Rosa\", \"Ranger Amarillo\"}\n\nrangers3 = append(rangers3, \"Ranger Blanco\")\n\nfmt.Println(\"Tamaño\", len(rangers3))\nfmt.Println(\"Capacidad\", cap(rangers3))\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Para nuestra sorpresa al ejecutar vemos esto:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen21.34.02.png","alt":""},"children":[]},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"UPS!!!"}]},{"type":"text","value":" "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"y que ha pasaaaaaooooo!!!????"}]},{"type":"text","value":", es simple Go lo que hace es duplicar la capacidad anterior, por lo que si no tenemos en cuenta y tratamos con slices muy grandes, por ejemplo imaginemos un array de 100 elementos, si añadimos 1 mas para hacer 101 tendriamos una capacidad de 200 siendo realmente inecesario."},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\nVeamoslo con un ejemplo añadiendo al código anterior los 2 rangers restantes:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["kg-card","kg-code-card","gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"rangers3 := []string{\"Ranger Rosa\", \"Ranger Amarillo\"}\n\nrangers3 = append(rangers3, \"Ranger Blanco\")\n\nfmt.Println(\"Tamaño\", len(rangers3))\nfmt.Println(\"Capacidad\", cap(rangers3))\n\nrangers3 = append(rangers3, \"Ranger Rojo\", \"Ranger Negro\")\n\nfmt.Println(\"Tamaño\", len(rangers3))\nfmt.Println(\"Capacidad\", cap(rangers3))\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Vemos que tenemos de repente una capacidad de 8:"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"img","properties":{"src":"https://jlgarcia.fulldev.ninja/assets/images/2017/07/Screen21.39.27.png","alt":""},"children":[]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Creo que con esto mas o menos queda clara la diferencia entre los arrays definidos y los slices, hablando de consumo de memoria y del propio uso de uno u otro, siempre sera recomendable tener arrays definidos, veremos más adelante alguna forma de pasar de uno a otro."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"En el próximo post veremos tambien como trabajar con ambos, para recorrerlos, por ejemplo, y varias cosas mas."}]},{"type":"text","value":"\n"},{"type":"comment","value":"kg-card-end: markdown"}],"data":{"quirksMode":false}},"tableOfContents":[{"id":"arraysdefinidos","heading":"Arrays definidos"},{"id":"slices","heading":"SLICES"},{"id":"lenycap","heading":"Len y Cap"}]},"featureImageSharp":{"base":"Untitled-2.png","publicURL":"/static/4c2a69b59a578389653f7d3cb966f439/Untitled-2.png","imageMeta":{"width":649,"height":244},"childImageSharp":{"fluid":{"base64":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsTAAALEwEAmpwYAAABr0lEQVQoz22RPWhTURiGP+29N/eec3/aK1FjI9RBm3aSSBVBDVSzOGpwiMEhKopmsCnYyUVQwS5WxKU6iGBwdOrQqZOD+EO1HYo/mCBtySSC6+O5CQVjHF7ecw7veb6Xc0RrTa8USnV9S57ZZ2LF3rTqeBwqhiIf3++X9AO3YN11AlfGx7KKyTGX4nhXx/YJg9pGZBuOYxs5WJbVC1QdQBfm6oAwCnl+wWFixDMXPbZbGjulicx58dQko6MHKBQK5HK5jvL5/D8NDcz3NQOO4khGaJSElxXh4knFiaMZTh/22b/HwbYdpms1zpVKTNXrlMtlKpUK1Wq1v2ECVdrHPVPi+N0pns2eZ/7FNFdeP+FVY4a5xzfZcf8BA9fr7B4eZjCKSKfTZLNZ4jj+D9B1CXbuQu495OzaBt/ffWJh5RvF5m9azTbrq2tMfN1E5uZRQYhn8q7nkUql8Iz3ApN2QUAggly6xsjndRY32zz68J6Dtcs8ffuG280NrC9trOpVfJPTYdjzoX1vmEzVJmjfmEFaP5HlJoeWllhuzFJYXEA+tpAfv7Bu3enkkrz6i/EHdxf7UmCHE+cAAAAASUVORK5CYII=","aspectRatio":2.6515151515151514,"src":"/static/4c2a69b59a578389653f7d3cb966f439/d382d/Untitled-2.png","srcSet":"/static/4c2a69b59a578389653f7d3cb966f439/847ef/Untitled-2.png 175w,\n/static/4c2a69b59a578389653f7d3cb966f439/91cba/Untitled-2.png 350w,\n/static/4c2a69b59a578389653f7d3cb966f439/d382d/Untitled-2.png 649w","srcWebp":"/static/4c2a69b59a578389653f7d3cb966f439/10386/Untitled-2.webp","srcSetWebp":"/static/4c2a69b59a578389653f7d3cb966f439/9fca7/Untitled-2.webp 175w,\n/static/4c2a69b59a578389653f7d3cb966f439/37a4e/Untitled-2.webp 350w,\n/static/4c2a69b59a578389653f7d3cb966f439/10386/Untitled-2.webp 649w","sizes":"(max-width: 649px) 100vw, 649px"}}}}}]}},"pageContext":{"slug":"go-go-power-ra-ah-que-no-go-parte-5-maps","prev":"react-superhero-introduccion","next":"cloud-adventures-android-y-azure-active-directory-login","tag":"go","limit":3,"skip":0,"primaryTagCount":6,"collectionPaths":{}}},
    "staticQueryHashes": ["1272700106","1676991999","2138873178","2546165603","2681841279","2938721187","293880488","3052966952","4156497161"]}