Copia de valor y referencia

https://medium.com/laboratoria-developers/por-valor-vs-por-referencia-en-javascript-de3daf53a8b9


const frutas = ['manzana', 'pera', 'kiwi']

const frutas2 = frutas // NO SE COPIA EL VALOR SE COPIA LA REFERENCIA Se apunta al mismo sitio
// Tanto frutas como frutas 2 son como una flecha que apunta al mismo contenido
// Si yo cambio fruta, también cambio fruta2
// Se suele decir que necesitamos 'clonar' el array

console.log(frutas)
console.log(frutas2)

frutas.push('melón')
console.log(frutas)
console.log(frutas2)

let a = 20
const b = a // Copiar el valor

a++
console.log(a) // 21
console.log(b) // 20

// a |20|

// frutas es un puntero al contenido del array
// frutas2=frutas lo que copio es la dirección no el contenido

const a = [1, 2, 3, 4]
console.log(sumaArray(a))
console.log(a)

// Esta función nos suma el array pero también nos lo destruye
// Porque no se pasa una copia se pasa el propio array
// la REFERENCIA al array. Mucho cuidado con esto
function sumaArray (array) {
  let suma = 0
  while (array.length > 0) {
    suma += array.pop()
  }
  return suma
}

// SOlución

function sumaArrayBien (array) {
  let suma = 0
  const copia = array.slice()
  while (copia.length > 0) {
    suma += copia.pop()
  }
  return suma
}

function sumaSinModificacion (array) {
  let suma = 0
  for (const v of array) {
    suma += v
  }
  return suma
}

Mini ejercicio arrays

Al darle al botón contar que nos diga el número de nombres que nos han introducido

<div class="container ">
		<div class="form-group">
			<label for="cadena">Nombre:</label>
			<input type="text" class="form-control" id="cadena">
		</div>

		<h1 id="posicion"></h1>
		<button type="button" class="btn btn-success" onclick="buscar()">Añadir</button>
		<button type="button" class="btn btn-success" onclick="contar()">Contar</button>
		<script src="js/test.js"></script>
		</form>
	</div>

const nombres = []
function buscar () {
  const nombre = document.getElementById('cadena').value
  nombres.push(nombre)
  console.log(nombres)
}

function contar () {
  document.getElementById('posicion').innerHTML = nombres.length
}

JS arrays primeros pasos

const variable = 'Manzana'
console.log(variable)
let cadena = variable + ' muy rica'

// Un array es una colección ordenada de variables
// Array, tablas, arreglos, tuplas
const misFrutas = ['Pera', 'Manzana', 'Melocotón']
console.log(misFrutas[0]) // Pera
console.log(misFrutas[2]) // Melocotón
console.log(misFrutas[3]) // Error: undefined

cadena = '1,2,3,4,5'
console.log(cadena)
const numeros = cadena.split(',')
console.log(numeros)
console.log(numeros[2]) // 3
const masNumeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
console.log(masNumeros)
for (let i = 0; i < misFrutas.length; i++) {
  console.log(misFrutas[i])
}
for (let i = 0; i < numeros.length; i++) {
  console.log(numeros[i])
}
for (let i = 0; i < masNumeros.length; i++) {
  console.log(masNumeros[i])
}

const tutiFruti = [1, 2, 'hola que tal', 7, false, 'p', 'papaya']
for (let i = 0; i < tutiFruti.length; i++) {
  console.log(tutiFruti[i])
}

numeros[2] = 'Cacahuete'
console.log(numeros)

for (let i = 0; i < masNumeros.length; i++) {
  if (masNumeros[i] % 2 == 0) {
    masNumeros[i]++
  } else {
    masNumeros[i]--
  }
}
console.log(masNumeros)

masNumeros = [2, 623, 312, 7, 234, 234, 3, 89]
// ¿Cuantos números pares hay en masNumeros?
let cont = 0
for (let i = 0; i < masNumeros.length; i++) {
  if (masNumeros[i] % 2 == 0) {
    cont++
  }
}
console.log('Hay ' + cont + ' pares')

// Añadir o quitar elementos del array
// pop push Nos quita el último elemento del array o nos añade un elemento al final del array

let miArray = ['a', 'b', 'c']
// Añade elementos al final
miArray.push('d')
console.log(miArray)
miArray.push('k')
console.log(miArray)
// Quita elementos del final
let elemento = miArray.pop()
console.log(miArray)
console.log(elemento)
const otro = []
otro.push(miArray.pop())
otro.push(miArray.pop())
console.log(otro)

// shift y unshift que es lo mismo pero del principio
miArray = ['a', 'b', 'c']
miArray.unshift('z')
console.log(miArray)
miArray.unshift('y')
console.log(miArray)
elemento = miArray.shift()
console.log(miArray)
console.log(elemento)

const enumeracion = []
for (let i = 0; i < 20; i++) {
  enumeracion.push(i)
}
console.log(enumeracion)

Ejercicio de ejemplo

Dada una frase, contar las palabras que tiene. Entendiendo que una palabra se distingue por estar entre espacios.

Cadena: «Hola que tal»
Tiene 3 palabras
Las palabas son las siguientes: Hola, que, tal

<div class="container ">
		<div class="form-group">
			<label for="cadena">cadena original:</label>
			<input type="text" class="form-control" id="cadena">
		</div>

		<h1 id="posicion"></h1>
		<button type="button" onclick="buscar()">Buscar</button>
		<script src="js/test.js"></script>
		</form>
	</div>

// Algoritmo: ¿Cómo soluciono el problema?
// Busco los espacios y cada vez que encuentro 1 sé que hay una palabra
// ¿Se buscar? Sí, con el indexOf Si yo modifico el código que ya tengo para que me busque un espacio
// Si yo tengo n espacio el número de palabras es n+1
// Buscar los espacios y con el slice ir cogiendo las palabras
// Si yo sustituyo los espacios por ‘, ‘ tengo lo que se busca
// Uso replace(/ /g,’, ‘)
// Si yo se que la longitud de una cadena es long
// Sustituyo todos los espacios por »
// Y miro cual es la longitud ahora de la cadena: longitud antes-longitud ahora=espacios
// Uso replace(/ /g,»)

function buscar () {
const cadena = document.getElementById(‘cadena’).value
let cont = 0
if (cadena != ») {
cont = apariciones(cadena, ‘ ‘) + 1
}
document.getElementById(‘posicion’).innerHTML = ‘El número de palabras es: ‘ + cont
}

// Separar palabras siguiendo la lógica del buscar
// Yo voy buscando los espacios y allí donde los encuentro
// Parto la cadena
function separarPalabras (cadena) {
// Busco la primera aparición del espacio
let pos = cadena.indexOf(‘ ‘)
// Necesito para partir una cadena un inicio y un fin
// El fin me lo da la posición que he encontrado, el inicio lo tengo que guardar
let anterior = 0
// Aquí iré añadiendo las palabras
let resultado = »
while (pos > -1) {
// Añado la palabra que será desde la posición anterior hasta la que acabo de encontrar
resultado += cadena.slice(anterior, pos) + ‘, ‘
// Guardo en anterior la posición + 1 porque me salto el espacio
anterior = pos + 1
// Busco la siguiente
pos = cadena.indexOf(‘ ‘, pos + 1)
}
// Añado la palabra final que como no tiene espacio no la hemos encontrado
resultado += cadena.slice(anterior)
return resultado
}

function separarConTrampa (cadena) {
// Reemplazar los espacios por comas
return cadena.replace(/ /g, ‘, ‘)
}

// Cuento las palabras eliminando los espacios y calculando la resta
function contarPalabras (cadena) {
// Normalizo la cadena quitando espacios que sobran
cadena = quitarEspaciosExtra(cadena)
// Elimino los espacios de la cadena utilizando la expresión regular
// ‘/ /g’ La g nos indica que queremos reemplazar todas las apariciones
const sinespacios = cadena.replace(/ /g, »)
// Tengo en cuenta el caso particular de que la cadena esté vacía
if (cadena == ») {
return 0
} else {
// Las palabras son los espacios + 1
return cadena.length – sinespacios.length + 1
}
}

// Crear una función que nos busque el número de apariciones de una cadena en otra
// En cadena le pasamos la cadena en la que vamos a buscar. Ej: «hola que tal»
// En buscar la cadena que vamos a buscar Ej «que»
function apariciones (cadena, buscar) {
// Búscame la primera aparición de la cadena buscar dentro de cadena
// Ej búscame la primera aparición de ‘que’ dentro de ‘hola que tal’ –> 5
let pos = cadena.indexOf(buscar)
// Como voy a contar me hace falta una variable para contar
let cont = 0
// Si la pos es -1 es porque no la ha encontrado, por lo tanto no entramos en el bucle
// Si la pos >-1 es porque SI la ha encontrado, por lo tanto entramos
while (pos > -1) {
// Si hemos entrado es porque la ha encontrado, por lo tanto contamos 1
cont++
// Buscamos la siguiente aparición de la palabra ¿Cómo?
// Buscando a partir de la posición que ya hemos encontrado->pos+1
// Ej: busco que a partir de la posición 6 pos-> -1
pos = cadena.indexOf(buscar, pos + 1)
}
// En el ejemplo que estamos analizando devuelve 1
return cont
}

function quitarEspaciosExtra (cadena) {
cadena = cadena.trim()
let res = cadena.slice(0, 1)
for (let i = 1; i < cadena.length; i++) { const carActual = cadena.slice(i, i + 1) const carAnterior = cadena.slice(i - 1, i) if (!(carActual == ' ' && carAnterior == ' ')) { res += carActual } } return res } function quitarEspacios (cadena) { while (cadena.indexOf(' ') > -1) {
cadena = cadena.replace(/ {2}/g, ‘ ‘)
}
return cadena
}
// hola que tal
// hola que tal
// hola que tal
// hola que tal

Ejercicio cadenas

Tenemos una web como las que hemos visto hasta ahora con un textbox de una cadena
Cadena:
Y otro textbox con una cadena a buscar
Buscar:

Cuando le demos a un botón de buscar nos mostrará por pantalla el número de veces que está la cadena buscada dentro de la cadena original.

Ejemplos:

Cadena: «Hola que pasa que comes queso»
Buscar: «Pepito»
Nos muestra 0
Cadena: «Hola que pasa que comes queso»
Buscar: «pasa»
Nos muestra 1
Cadena: «Hola que pasa que comes queso»
Buscar: «que»
Nos muestra 3

Ejemplo replace normal y con regexp

<!DOCTYPE html>
<html>

<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>

<body>
	<div class="container ">
		<div class="form-group">
			<label for="cadena">Cadena original:</label>
			<input type="text" class="form-control" id="cadena">
		</div>
		<div class="form-group">
			<label for="cadena">Cadena a eliminar:</label>
			<input type="text" class="form-control" id="quitar">
		</div>
		<h1 id="posicion"></h1>
		<button type="button" class="btn btn-success" onclick="quitar()">Buscar</button>
		<script src="js/test.js"></script>
		</form>
	</div>
</body>

</html>

function quitar () {
  const cadena = document.getElementById('cadena').value
  const quitar = document.getElementById('quitar').value

  // Esto es una expresión regular, que son MUY POTENTES y se usan muchísimo
  // Pero que veremos más adelante
  // Pero... nos sirve como truco para usar usando aquello del CTRL+C CTRL+V
  // Reemplace todas las apariciones de quitar (g) insensible a mayúsculas (i)
  const reg = new RegExp(quitar, 'gi')
  document.getElementById('posicion').innerHTML = cadena.replace(reg, '')
}

function quitarOld () {
  let cadena = document.getElementById('cadena').value
  const quitar = document.getElementById('quitar').value
  while (cadena.indexOf(quitar) > -1) {
    cadena = cadena.replace(quitar, '#')
  }
  document.getElementById('posicion').innerHTML = cadena
}

Ejemplo slice

<!DOCTYPE html>
<html>

<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>

<body>
	<div class="container ">
		<div class="form-group">
			<label for="cadena">Cadena original:</label>
			<input type="text" class="form-control" id="cadena">
		</div>
		<div class="form-group">
			<label for="cadena">Cadena a eliminar:</label>
			<input type="text" class="form-control" id="quitar">
		</div>
		<h1 id="posicion"></h1>
		<button type="button" class="btn btn-success" onclick="quitar()">Buscar</button>
		<script src="js/test.js"></script>
		</form>
	</div>
</body>

</html>
function quitar () {
  let cadena = document.getElementById('cadena').value
  const quitar = document.getElementById('quitar').value
  const pos = cadena.indexOf(quitar)
  if (pos > -1) {
    cadena = cadena.slice(0, pos) + cadena.slice(pos + quitar.length)
  }
  document.getElementById('posicion').innerHTML = cadena
}

Ejemplo subst

<!DOCTYPE html>
<html>

<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>

<body>
	<div class="container ">
		<div class="form-group">
			<label for="cadena">cadena original:</label>
			<input type="text" class="form-control" id="cadena">
		</div>
		<div class="form-group">
			<label for="cadena">tamaño:</label>
			<input type="text" class="form-control" id="tamany">
		</div>
		<h1 id="posicion"></h1>
		<button type="button" class="btn btn-success" onclick="buscar2()">Buscar</button>
		<script src="js/test.js"></script>
		</form>
	</div>
</body>

</html>
function buscar () {
  let cadena = document.getElementById('cadena').value
  const tamany = parseFloat(document.getElementById('tamany').value)

  // Vacío el HTML para poner nuevos valores
  document.getElementById('posicion').innerHTML = ''
  // Si la cadena no está vacía
  while (cadena.length > 0) {
    // Pon en el html un fragmento de la cadena de longitud 'tamany' y una coma
    document.getElementById('posicion').innerHTML += cadena.substr(0, tamany) + ', '
    // Quítale a la cadena el fragmento que he puesto en el HTML
    cadena = cadena.substr(tamany)
  }
  // Le quito la coma final
  document.getElementById('posicion').innerHTML = document.getElementById('posicion').innerHTML.slice(0, -2)
}

function buscar2 () {
  const cadena = document.getElementById('cadena').value
  const tamany = parseFloat(document.getElementById('tamany').value)

  // Vacío el HTML para poner nuevos valores
  document.getElementById('posicion').innerHTML = ''

  // Como sé que tengo que empezar en el 0 y acabar en la longitud de la cadena
  // Puedo utilizar un for
  for (let i = 0; i < cadena.length; i += tamany) {
    document.getElementById('posicion').innerHTML += cadena.substr(i, tamany) + ', '
  }
  // Le quito la coma final
  document.getElementById('posicion').innerHTML = document.getElementById('posicion').innerHTML.slice(0, -2)
}

Ejercicio búsqueda múltiple

<!DOCTYPE html>
<html>

<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>

<body>
	<div class="container ">
		<div class="form-group">
			<label for="cadena">cadena original:</label>
			<input type="text" class="form-control" id="cadena">
		</div>
		<div class="form-group">
			<label for="cadena">cadena a buscar:</label>
			<input type="text" class="form-control" id="buscar">
		</div>
		<h1 id="posicion"></h1>
		<button type="button" onclick="buscar()">Buscar</button>
		<script src="js/test.js"></script>
		</form>
	</div>
</body>

</html>
function buscar () {
  const cadena = document.getElementById('cadena').value
  const buscar = document.getElementById('buscar').value
  document.getElementById('posicion').innerHTML = ''
  let pos = cadena.indexOf(buscar)
  // ¿Cuando tenemos que parar la búsqueda? Cuando no encuentre la cadena a buscar
  // ¿Cómo se yo que no la ha encontrado? Porque indexOf devuelve -1
  // ¿Cual es la condición del while? Mientras la posición no sea -1 es que ha encontrado algo
  // Mientras pos>-1 sigue buscando porque la hemos encontrado
  while (pos > -1) {
    document.getElementById('posicion').innerHTML += pos + ','
    pos = cadena.indexOf(buscar, pos + 1)
  }
}
// cadena="En un lugar de la mancha"
// buscar="a"
// Busca la 'a'. La encuentra en la posición 9
// ¿Es 9 mayor que -1? Sí por lo tanto
// Lo pone en el HTML 9,
// Y buscamos la aparición de 'a' a partir de la pos+1, es decir
// Buscamos la 'a' a partir de la posición 10
// La encuentra en la posición 16
// ¿Es 16 mayor que -1? Sí por lo tanto
// Lo pone en el HTML 16,
// Y buscamos la aparición de 'a' a partir de la pos+1, es decir
// Buscamos la 'a' a partir de la posición 17
// La encuentra en la posición 19
// ¿Es 19 mayor que -1? Sí por lo tanto
// Lo pone en el HTML 19,
// Y buscamos la aparición de 'a' a partir de la pos+1, es decir
// Buscamos la 'a' a partir de la posición 20
// Buscamos la 'a' a partir de la posición 20
// La encuentra en la posición 23
// ¿Es 23 mayor que -1? Sí por lo tanto
// Lo pone en el HTML 23,
// Y buscamos la aparición de 'a' a partir de la pos+1, es decir
// Buscamos la 'a' a partir de la posición 24
// Ya no encuentra la 'a', devuelve -1 y salimos del bucle

// Es MUY DIFERENTE
// pos++ que pos+1
// pos++ es una instrucción que modifica el valor de pos: pos=pos+1 Si pos vale 3 pasa a valer 4
// pos+1 es un valor. Que vale lo que valga pos + 1 (ej 3->4) pero que no modifica nada