|
| 1 | +# Reto 18: La-agenda-magica-de-santa |
| 2 | + |
| 3 | +Santa Claus tiene una agenda mágica 📇 donde guarda las direcciones de los niños para entregar los regalos. El problema: **la información de la agenda está mezclada y malformateada**. Las líneas contienen un número de teléfono mágico, el nombre de un niño y su dirección, pero todo está rodeado de caracteres extraños. |
| 4 | + |
| 5 | +Santa necesita tu ayuda para encontrar información específica de la agenda. Escribe una función que, **dado el contenido de la agenda y un número de teléfono, devuelva el nombre del niño y su dirección.** |
| 6 | + |
| 7 | +Ten en cuenta que en la agenda: |
| 8 | + |
| 9 | +- Los números de teléfono están formateados como +X-YYY-YYY-YYY (donde X es uno o dos dígitos, e Y es un dígito). |
| 10 | +- El nombre de cada niño está siempre entre < y > |
| 11 | + |
| 12 | +La idea es que escribas una funcióna que, pasándole el teléfono completo o una parte, devuelva el nombre y dirección del niño. **Si no encuentra nada o hay más de un resultado**, debes devolver `null`. |
| 13 | + |
| 14 | +```js |
| 15 | +const agenda = `+34-600-123-456 Calle Gran Via 12 <Juan Perez> |
| 16 | +Plaza Mayor 45 Madrid 28013 <Maria Gomez> +34-600-987-654 |
| 17 | +<Carlos Ruiz> +1-800-555-0199 Fifth Ave New York` |
| 18 | + |
| 19 | +findInAgenda(agenda, '34-600-123-456') |
| 20 | +// { name: "Juan Perez", address: "Calle Gran Via 12" } |
| 21 | + |
| 22 | +findInAgenda(agenda, '600-987') |
| 23 | +// { name: "Maria Gomez", address: "Plaza Mayor 45 Madrid 28013" } |
| 24 | + |
| 25 | +findInAgenda(agenda, '111') |
| 26 | +// null |
| 27 | +// Explicación: No hay resultados |
| 28 | + |
| 29 | +findInAgenda(agenda, '1') |
| 30 | +// null |
| 31 | +// Explicación: Demasiados resultados |
| 32 | +``` |
| 33 | + |
| 34 | +## Mi solución explicada |
| 35 | + |
| 36 | +```js |
| 37 | +function findInAgenda(agenda, phone) { |
| 38 | + const kidsList = agenda.split('\n'); |
| 39 | + const foundKids = kidsList.filter((kid) => kid.includes(phone)); |
| 40 | + |
| 41 | + const matchingCount = foundKids?.length; |
| 42 | + |
| 43 | + if (matchingCount === 1) { |
| 44 | + const [firstKid] = foundKids; |
| 45 | + const name = firstKid.split('<')[1].split('>')[0]; |
| 46 | + const address = firstKid |
| 47 | + .split(' ') |
| 48 | + .slice(1, -1) |
| 49 | + .join(' ') |
| 50 | + .split('<')[0] |
| 51 | + .trim(); |
| 52 | + |
| 53 | + return { name, address }; |
| 54 | + } |
| 55 | + |
| 56 | + return null; |
| 57 | +} |
| 58 | +``` |
| 59 | +
|
| 60 | +Para resolver este reto, primero dividí la agenda en una lista de niños por cada salto de línea. |
| 61 | +
|
| 62 | +Luego, filtré la lista de niños para encontrar aquellos que contienen el número de teléfono que se busca y guardé el resultado en `foundKids`. |
| 63 | +
|
| 64 | +Después, conté cuántos niños coinciden con el número de teléfono buscado y guardé el resultado en `matchingCount`. |
| 65 | +
|
| 66 | +Em este caso si no hay resultados o hay más de uno, devuelvo `null` porque como dice el enunciado, si no hay resultados o hay más de un resultado, debes devolver `null`. |
| 67 | +
|
| 68 | +Si hay un solo resultado, extraigo el nombre y la dirección del niño y los devuelvo en un objeto. |
| 69 | +
|
| 70 | +Para obtener el nombre del niño, busco el texto que está entre los caracteres `<` y `>`. |
| 71 | +
|
| 72 | +Para obtener la dirección del niño, elimino el número de teléfono y el nombre del niño de la cadena, y luego elimino los espacios en blanco al principio y al final de la cadena. |
| 73 | +
|
| 74 | +Finalmente, devuelvo un objeto con el nombre y la dirección del niño. |
| 75 | +
|
| 76 | +**Veamos con un ejemplo cómo funciona**: |
| 77 | +
|
| 78 | +Supongamos que tenemos la siguiente agenda: |
| 79 | +
|
| 80 | +```js |
| 81 | +const agenda = `+34-600-123-456 Calle Gran Via 12 <Juan Perez> |
| 82 | +Plaza Mayor 45 Madrid 28013 <Maria Gomez> +34-600-987-654 |
| 83 | +<Carlos Ruiz> +1-800-555-0199 Fifth Ave New York` |
| 84 | +``` |
| 85 | +
|
| 86 | +y queremos buscar el número de teléfono `34-600-123-456`. |
| 87 | +
|
| 88 | +Primero, dividimos la agenda en una lista de niños: |
| 89 | +
|
| 90 | +```js |
| 91 | +const kidsList = agenda.split('\n'); |
| 92 | + |
| 93 | +// kidsList = [ |
| 94 | +// '+34-600-123-456 Calle Gran Via 12 <Juan Perez>', |
| 95 | +// 'Plaza Mayor 45 Madrid 28013 <Maria Gomez> +34-600-987-654', |
| 96 | +// '<Carlos Ruiz> +1-800-555-0199 Fifth Ave New York' |
| 97 | +// ] |
| 98 | +``` |
| 99 | +
|
| 100 | +Despues filtramos la lista de niños para encontrar aquellos que contienen el número de teléfono que buscamos: |
| 101 | +
|
| 102 | +Al utilizar el método `filter` con la condición `kid.includes('34-600-123-456')`, obtenemos un nuevo array con los niños que contienen el número de teléfono buscado. Ya que la cadena `'+34-600-123-456 Calle Gran Via 12 <Juan Perez>'` contiene el número de teléfono `34-600-123-456`. |
| 103 | +
|
| 104 | +```js |
| 105 | +const foundKids = kidsList.filter((kid) => kid.includes('34-600-123-456')); |
| 106 | + |
| 107 | +// foundKids = [ |
| 108 | +// '+34-600-123-456 Calle Gran Via 12 <Juan Perez>' |
| 109 | +// ] |
| 110 | +``` |
| 111 | +
|
| 112 | +Luego, contamos cuántos niños coinciden con el número de teléfono buscado: |
| 113 | +
|
| 114 | +```js |
| 115 | +const matchingCount = foundKids?.length; |
| 116 | +const matchingCount = 1; |
| 117 | +``` |
| 118 | +
|
| 119 | +Ahora validamos la condición que nos dice que si no hay resultados o hay más de uno, debemos devolver `null`. En este caso, como hay un solo resultado, extraemos el nombre y la dirección del niño y los devolvemos en un objeto: |
| 120 | +
|
| 121 | +```js |
| 122 | +const [firstKid] = foundKids; |
| 123 | +const name = firstKid.split('<')[1].split('>')[0]; |
| 124 | + |
| 125 | +// const name = '+34-600-123-456 Calle Gran Via 12 <Juan Perez>'.split('<')[1].split('>')[0]; |
| 126 | +// const name = ['+34-600-123-456 Calle Gran Via 12 ', 'Juan Perez>'][1].split('>')[0]; |
| 127 | +// const name = ['Juan Perez>'].split('>')[0]; |
| 128 | +// const name = ['Juan Perez', ''][0]; |
| 129 | +const name = 'Juan Perez'; |
| 130 | + |
| 131 | +const address = firstKid |
| 132 | + .split(' ') |
| 133 | + .slice(1, -1) |
| 134 | + .join(' ') |
| 135 | + .split('<')[0] |
| 136 | + .trim(); |
| 137 | + |
| 138 | +// const address = '+34-600-123-456 Calle Gran Via 12 <Juan Perez>'.split(' ').slice(1, -1).join(' ').split('<')[0].trim(); |
| 139 | +// const address = ['+34-600-123-456', 'Calle', 'Gran', 'Via', '12', '<Juan', 'Perez>'].slice(1, -1).join(' ').split('<')[0].trim(); |
| 140 | +// const address = ['Calle', 'Gran', 'Via', '12', '<Juan'].join(' ').split('<')[0].trim(); |
| 141 | +// const address = 'Calle Gran Via 12 <Juan'.split('<')[0].trim(); |
| 142 | +// const address = ['Calle Gran Via 12 ', 'Juan'][0].trim(); |
| 143 | +// const address = 'Calle Gran Via 12 '.trim(); |
| 144 | +const address = 'Calle Gran Via 12'; |
| 145 | + |
| 146 | +return { name, address }; |
| 147 | + |
| 148 | +// { name: "Juan Perez", address: "Calle Gran Via 12" } |
| 149 | +``` |
| 150 | +
|
| 151 | +Finalmente, devolvemos un objeto con el nombre y la dirección del niño. |
| 152 | +
|
| 153 | +**Ahora veamos un caso en el que pueden haber más de un resultado**: |
| 154 | +
|
| 155 | +Supongamos que queremos buscar el número de teléfono `1`. |
| 156 | +
|
| 157 | +Primero, dividimos la agenda en una lista de niños: |
| 158 | +
|
| 159 | +```js |
| 160 | +const kidsList = agenda.split('\n'); |
| 161 | + |
| 162 | +// kidsList = [ |
| 163 | +// '+34-600-123-456 Calle Gran Via 12 <Juan Perez>', |
| 164 | +// 'Plaza Mayor 45 Madrid 28013 <Maria Gomez> +34-600-987-654', |
| 165 | +// '<Carlos Ruiz> +1-800-555-0199 Fifth Ave New York' |
| 166 | +// ] |
| 167 | +``` |
| 168 | +
|
| 169 | +Despues filtramos la lista de niños para encontrar aquellos que contienen el número de teléfono que buscamos: |
| 170 | +
|
| 171 | +Al utilizar el método `filter` con la condición `kid.includes('1')`, obtenemos un nuevo array con los niños que contienen el número de teléfono buscado. Ya que las cadenas `'<Carlos Ruiz> +1-800-555-0199 Fifth Ave New York'` y `'<Carlos Ruiz> +1-800-555-0199 Fifth Ave New York'` contienen el número de teléfono `1`. |
| 172 | +
|
| 173 | +```js |
| 174 | +const foundKids = kidsList.filter((kid) => kid.includes('1')); |
| 175 | + |
| 176 | +// kidsFound: [ |
| 177 | +// '+34-600-123-456 Calle Gran Via 12 <Juan Perez>', |
| 178 | +// 'Plaza Mayor 45 Madrid 28013 <Maria Gomez> +34-600-987-654', |
| 179 | +// '<Carlos Ruiz> +1-800-555-0199 Fifth Ave New York' |
| 180 | +// ] |
| 181 | +``` |
| 182 | +
|
| 183 | +Luego, contamos cuántos niños coinciden con el número de teléfono buscado: |
| 184 | +
|
| 185 | +```js |
| 186 | +const matchingCount = foundKids?.length; |
| 187 | +const matchingCount = 3; |
| 188 | +``` |
| 189 | +
|
| 190 | +Ahora validamos la condición que nos dice que si no hay resultados o hay más de uno, debemos devolver `null`. En este caso, como hay más de un resultado, devolvemos `null`. |
| 191 | +
|
| 192 | +```js |
| 193 | +if (matchingCount === 1) {...} |
| 194 | +if (3 === 1) {...} |
| 195 | +if (false) {...} // No se cumple la condición |
| 196 | + |
| 197 | +return null; |
| 198 | +``` |
| 199 | +
|
| 200 | +Finalmente, devolvemos `null` porque hay más de un resultado. |
| 201 | +
|
| 202 | +```js |
| 203 | +return null; |
| 204 | +``` |
| 205 | +
|
| 206 | +Y eso es todo. Esa es la solución al reto 🎉 |
0 commit comments