{
    "componentChunkName": "component---node-modules-gatsby-theme-try-ghost-src-templates-post-js",
    "path": "/cloud-adventures-android-y-azure-active-directory-login/",
    "result": {"data":{"ghostPost":{"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.6455696202531647,"src":"/static/258a34bdac22a1c7f123fe43c9931f62/d1e92/cloud-ninjaaz.png","srcSet":"/static/258a34bdac22a1c7f123fe43c9931f62/bcfcb/cloud-ninjaaz.png 260w,\n/static/258a34bdac22a1c7f123fe43c9931f62/19d75/cloud-ninjaaz.png 520w,\n/static/258a34bdac22a1c7f123fe43c9931f62/d1e92/cloud-ninjaaz.png 777w","srcWebp":"/static/258a34bdac22a1c7f123fe43c9931f62/60436/cloud-ninjaaz.webp","srcSetWebp":"/static/258a34bdac22a1c7f123fe43c9931f62/dc8f3/cloud-ninjaaz.webp 260w,\n/static/258a34bdac22a1c7f123fe43c9931f62/2db4b/cloud-ninjaaz.webp 520w,\n/static/258a34bdac22a1c7f123fe43c9931f62/60436/cloud-ninjaaz.webp 777w","sizes":"(max-width: 777px) 100vw, 777px"}}}},"prev":{"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.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"}}}},"next":{"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"}}}},"allGhostPost":{"edges":[]}},"pageContext":{"slug":"cloud-adventures-android-y-azure-active-directory-login","prev":"go-go-power-ra-ah-que-no-go-parte-5-maps","next":"go-parte-4-arrays-y-slices-ii","tag":"azure","limit":3,"skip":0,"primaryTagCount":1,"collectionPaths":{}}},
    "staticQueryHashes": ["1272700106","1676991999","2138873178","2546165603","2681841279","2938721187","293880488","3052966952","4156497161"]}