Repaso parte programación

// Variables
let c = "Hola que tal";
let n = 9;
let b = false;

n++;
c += " yo muy bien";

console.log(n);
console.log(c);

// Estructuras de control if (condicion){} else{}
if (n > 5) {
    console.log("Lo que pasa si n es mayor de 5");
} else { // opcional
    console.log("Lo que pasa si es menor");
}

// Las condiciones pueden ser complejas y utilizar los operadores lógicos
// AND && OR || NOT !
if (n > 5 && n < 10) {
    console.log("N es mayor de 5 Y menor de 10");
}
if (n == 5 || n == 6) {
    console.log("N es igual a 5 O igual a 6")
}

if (!(n == 5 || n == 6)) {
    console.log("N NO es igual a 5 ni igual a 6")
}

// switch nos evalua un valor y lo compara
switch (n) {
    case 1, 2, 3:
        console.log("N val 1, 2 o 3");
        break; // Romper el switch porque no si no sigue para adelante
    case 4:
        console.log("N vale 4");
        break;
    default:
        console.log("Cualquier otro valor")
}

let dia = "domingo";
switch (dia) {
    case "lunes":
    case "martes":
    case "miércoles":
    case "jueves":
        console.log("A trabajar");
        break;
    case "viernes":
        console.log("Por fin es viernes");
        break;
    case "sábado":
    case "domingo":
        console.log("Fin de semana");
        break;
    default:
        console.log("Día erróneo");
}

// if..else if.. else if
if (dia == "lunes" || dia == "martes" || dia == "miercoles" || dia == "jueves") {
    console.log("A trabajar");
} else if (dia == "viernes") {
    console.log("Por fin es viernes");
} else if (dia == "sábado" || dia == "domingo") {
    console.log("Fin de semana");
} else {
    console.log("Día erróneo");
}

let cantidad = 500;
if (cantidad < 100) {
    //-...
} else if (cantidad < 1000) {

} else if (cantidad < 5000) {

}

// Bucles
let i=0;
while(i<10){ // Mientras se cumpla esta condición
    i++;
    console.log(i)
}

do{
    i--;
    console.log(i)
} while(i>0);

// Bucle for(inicializacion,condicion,modificacion)
for(let i=0;i<10;i++){
    console.log(i);
}
for(let i=0;i<100;i+=5){
    console.log(i);
}

// Ámbito de las variables
// Una variable es visible dentro de las llaves donde está declarada

for(let i=0;i<10;i++){
    let j=i*4; // j solo es visible dentro del bucle
    console.log(i,j);
}
// console.log(j); // No existe

// funciones: nos permiten encapsular código
// Pueden tener parámetros y devolver resultados

function saludo(){
    console.log("Hola");
}
function saludo2(nombre){
    console.log("Hola "+nombre);
}
function saludo3(nombre){
    return "Hola "+nombre;
}

// Función pura: no depende de nada del entorno para ejecutarse
// Es como una caja negra, recoge parámetros y devuelve resultados
// Ante los mismos parámetros devuelve los mismos resultados

function suma(a,b){
    return a+b;
}

// No pura
let num1=5;
let num2=6;
function suma(){
    return num1+num2; // Esto funciona porque existen variables en el código, pero si o existieran daría error
}

// Nosotros tenemos funciones matemáticas en el objeto Math
console.log(Math.sqrt(81));
console.log(Math.PI);
console.log(Math.random());

// Las cadenas tienen sus propios métodos

let cadena="Hola que tal";

console.log(cadena.toUpperCase());
console.log(cadena.slice(3,6));
console.log(cadena.at(-3));
console.log(cadena.indexOf("que"));

// Arrays
// Colección o lista de elementos, se definen con []
let notas=[1,2,3,4];
let alumnos=["Ana","Eva","Pep"];

// Recorrer un array
for(let i=0;i<notas.length;i++){
    console.log(notas[i]);
}

// for of
for(let nota of notas){
    console.log(nota);
}

//foreach
notas.forEach(function(valor){
    console.log(valor);
})

// Array tiene sus métodos
notas.push(8); // Añade una nota
let nota=notas.pop(); // Nos quita la última nota
console.log(nota);

notas.at(-1); // último elemento del array

console.log(notas.slice(2,3))// Obtengo una parte del array

// Splice: navaja suiza. Posición donde intervengo, elemntos eliminados, añadir elementos

alumnos.splice(1,1,"Juan","Luis"); // En la posición 1 elimina un elemento y pon Juan y Luis
console.log(alumnos);

console.log(alumnos.includes("Juan"));
console.log(alumnos.indexOf("Juan"));

// Funciones de iteracción. Todas hacen una copia

console.log(notas.filter(nota=>nota%2==0));
console.log(notas.map(nota=>nota*2));

// Objetos nos permiten tener información estructurada
// Un objeto tiene varias propiedades que pueden tener cualquier valor
let alumno={
    nombre:"Juan",
    email:"j@j.com"
}
let mascota={
    nombre:"Toby",
    edad:12
}
console.log(mascota.edad);

// Puedo tener mezcla de todo (y esto es habitual)

let mascotas=[
    {
        nombre:"Toby",
        edad:12
    },{
        nombre:"firulai",
        edad:5
    },{
        nombre:"Bestia",
        edad:3
    },{
        nombre:"Piolín",
        edad:8
    },{
        nombre:"Jerry",
        edad:9,
        enfermedades:["soriasis","parásitos"]
    },{
        nombre:"Sultán",
        edad:2
    }
]

// mascotas es un array por lo que lo recorro como tal

for(let m of mascotas){
    if(m.edad>7){
        console.log(m);
        if (m.enfermedades){
            console.log(`${m.nombre} ha enfermado`);
            for(let enf of m.enfermedades){
                console.log(enf);
            }
        }
    }
}

Soluciones ejercicios objetos

/* crear un objeto que nos permita almacenar la información de un producto,
 que consiste en un nombre, una referencia (ambas de tipo string) 
 y un precio y un stock (ambas de tipo numérico). */

let producto = {
    nombre: "Tuerca",
    referencia: "TRC45",
    precio: 10,
    stock: 30
}
console.log(producto)

// Crear un array con 3 elementos
let productos = [{
    nombre: "Tuerca",
    referencia: "TRC45",
    precio: 100,
    stock: 30
}, {
    nombre: "Clavo",
    referencia: "CLV",
    precio: 20,
    stock: 40
}, {
    nombre: "Arandela",
    referencia: "ARL67",
    precio: 30,
    stock: 50
}]
console.log(productos)

let inventario = [];
inventario.push({
    nombre: "Tuerca",
    referencia: "TRC45",
    precio: 100,
    stock: 30
});
inventario.push({
    nombre: "Tuerca",
    referencia: "TRC45",
    precio: 10,
    stock: 30
});
inventario.push({
    nombre: "Tuerca",
    referencia: "TRC45",
    precio: 10,
    stock: 30
});

// Con constructores
function Producto(nombre, referencia, precio, stock) {
    this.nombre = nombre;
    this.referencia = referencia;
    this.precio = precio;
    this.stock = stock;
}

let tienda = [new Producto("Aa", "BB", 1, 2),
new Producto("CC", "DD", 3, 4),
new Producto("EE", "FF", 5, 6),
];
console.log(tienda)

// Para sumar el stock tengo que recorrer el array

let sumaStock = 0;
// Manera clásica
for (let i = 0; i < productos.length; i++) {
    sumaStock += productos[i].stock; // accedo a la propiedad stock del producto
}
console.log(sumaStock)

sumaStock = 0;
// con for of
for (let p of productos) {
    sumaStock += p.stock;
}
console.log(sumaStock)

// con foreach
sumaStock = 0;
productos.forEach(function (prod) {
    sumaStock += prod.stock;
})
console.log(sumaStock);

function getSumaStock(productos) {
    sumaStock = 0;
    productos.forEach(function (prod) {
        sumaStock += prod.stock;
    });
    return sumaStock;
}

// Inicializo con el primero porque no sé que valores me voy a encontrar
let masCaro=productos[0];
for (let p of productos) {
    if (p.precio>masCaro.precio){
        masCaro=p;
    }
}
console.log(masCaro);
// Esto es más fácil de programar pero es mucho más costoso computacionalmente
productos.sort((a,b)=>a.precio-b.precio);
console.log(productos)
console.log(productos.at(-1))

productos.forEach(function (prod) {
    prod.stock+=10;
});

console.log(productos);

Ejemplos objetos

let alumno = {
    nombre: "Ana",
    email: "ana@ana.com",
    telefono: "666999666",
    saludo: function () {
        return "Hola soy "+this.nombre+" y mi número de teléfono es "+this.telefono+" ¡Llámame!";
    },
    despedida:function(){
        return `Adios, mi mail es ${this.email}`;
    }
}

console.log(alumno)
console.log(alumno.nombre)
console.log(alumno.telefono)
alumno.nombre = "Ana Pi";
console.log(alumno);
// Cuidado porque estamos añadiendo una propiedad nueva
alumno.telfono = "232323";
console.log(alumno);
// Accedo vía corchetes
alumno["email"] = "a@a.com";
console.log(alumno)

let prop = "telefono";
// Esto me permite acceder con variables
alumno[prop] = "1111111"; // alumno.telefono="1111111"
console.log(alumno)

// Recorro todas las propiedades de un objeto y con el corchete al valor
for (let propiedad in alumno) {
    console.log(propiedad, alumno[propiedad])
}

console.log(alumno.saludo());
console.log(alumno.despedida());

// Constructor de objetos
function Alumno(nombre,edad,email){
    this.nombre=nombre;
    this.edad=edad;
    this.email=email;
}

let ana=new Alumno("ana",20,"a@a.com");
let pep=new Alumno("pep",12,"p@a.com");

console.log(ana)
console.log(pep)

let ana={
    nombre:"Ana",
    edad:20,
    mayorEdad:function(){
        return this.edad>=18; //Accedo a las propiedades del objeto
    }
}

console.log(ana.mayorEdad()); // true porque edad es mayor de 18

ana.edad=15;
console.log(ana.mayorEdad()); //false porque edad es menor de 18

let alumnos=[{nombre:"Ana",edad:20},{nombre:"Eva",edad:16},{nombre:"Pep",edad:21},{nombre:"Juan",edad:30}];
console.log(alumnos)
alumnos.sort(function(a,b){
    return a.edad-b.edad
})
console.log(alumnos)
console.log(alumnos.filter(function(valor){
    return valor.edad>=18;
}))
let alumno={
    nombre:"Ana",
    notas:[4,7,2,3]
}
console.log(alumno)

let clase=[{nombre:"Ana",edad:20,notas:[{asignatura:"js",nota:6},{asignatura:"java",nota:4}]},{nombre:"Eva",edad:16},{nombre:"Pep",edad:21},{nombre:"Juan",edad:30}];
console.log(clase);

console.log(clase[0].notas[0].asignatura); //js


Ordenar en JS

let alumnos=["Juan","Ana","Pep","Eva"];
console.log(alumnos);
alumnos.sort();
console.log(alumnos);
alumnos.reverse();
console.log(alumnos);

let notas=[1,4,2,8,9,10,6];
console.log(notas);
notas.sort();
console.log(notas);
// Utilizamos una función propia
notas.sort(function(a,b){return a-b;});
console.log(notas);
// Con la función flecha es más corto
notas.sort((a,b)=> a-b);
console.log(notas);
let cadenas=["patatas","traigo","al","mercado"];
// Ordeno por longitud
cadenas.sort((a,b)=>a.length-b.length);
console.log(cadenas);
console.log(cadenas[0]); // La mas corta
console.log(cadenas.at(-1)); // La más larga

let productos=["Tuerca","Arandela","Clavo"];
let ordenados=productos.toSorted(); // Ordena creando una copia
console.log(productos);
console.log(ordenados);

// Desordenar (pero no es la mejor manera)
notas.sort(()=>0.5-Math.random());

console.log(notas)

Solución ejercicios

/*
Crear una función aprobados a la que le pasamos un array de notas y nos devuelve
 un array con las notas de los aprobados.*/

/**
 * 
 * @param {Array} lista de notas
 * @returns array con las notas>=5
 */
function aprobados(lista) {
    // Recorrer la lista y almacenar los que son mayor de 5
    let res = [];
    for (let nota of lista) {
        if (nota >= 5) {
            res.push(nota);
        }
    }
    return res;
}
function aprobados2(lista) {
    return lista.filter(function (valor) {
        return valor >= 5;
    })
}
let notas = [1, 4, 7, 8]
console.log(aprobados(notas)); // [7,8]
console.log(aprobados2(notas)); // [7,8]

/*
Crear una función aprobadosNota a la que le pasamos un array de notas y una nota de corte
y nos devuelve un array con las notas que superan o igualan la nota de corte. 
El valor por defecto de la nota de corte es 5
notas=[2,4,6,8,10]
aprobadosNota(notas) ->[6,8,10]
aprobadosNota(notas,7) ->[8,10]
*/
/**
 * 
 * @param {Array} lista de notas 
 * @param {Number} nota de corte 
 * @returns {Array} lista de notas que superan la nota de corte
 */
function aprobadosNota(notas, corte = 5) {
    return notas.filter(function (valor) {
        return valor >= corte;
    })
}

notas = [2, 4, 6, 8, 10]
console.log(aprobadosNota(notas)); //[6,8,10]
console.log(aprobadosNota(notas, 7));//[8,10]
/*
Crear una función a la que le pasemos un número y nos devuelva un array con 
los números desde el 1 al número que me pasen. 
Ejemplo, si le paso un 5 me devuelve [1,2,3,4,5] */

/**
 * 
 * @param {Number} numero hasta el que crear el rango
 * @returns Un array de 1 hasta el número que nos pasan
 */
function crearRango(numero){
    let res=[];
    for(let i=1;i<=numero;i++){
        res.push(i);
    }
    return res;
}
console.log(crearRango(5)); // [1,2,3,4,5]

/*
Una función estaOrdenado que nos devuelva true si le pasamos un array ordenado
 y false en caso contrario. Ojo, no que lo ordene, que nos diga si está ordenado.
  Ej: estaOrdenado([1,4,7])->true estaOrdenado([1,4,3])->false */

  /**
   * 
   * @param {Array} lista de números
   * @returns {Boolean} Devuelve si está ordenado o no
   */
function estaOrdenado(lista){
    let res=true;
    for(let i=1;i<lista.length;i++){
        if (lista[i]<lista[i-1]){
            res=false;
        }
    }
    return res;
}
function estaOrdenado2(lista){
    let res=true;
   lista.forEach(function(valor,indice,tabla){
    if (indice>0 && valor<tabla[indice-1]){
        res= false;
    }
   })
    return res;
}
console.log(estaOrdenado([1,4,7])); // true
console.log(estaOrdenado([1,4,3])); // false
console.log(estaOrdenado2([1,4,7])); // true
console.log(estaOrdenado2([1,4,3])); // false

/*
Crear una función masCorta(cadenas) a la que le pasamos un array de cadenas y nos 
devuelva la cadena más corta. Si hay dos o más cadenas con la misma longitud
 cualquiera de ellas
*/
/**
 * 
 * @param {Array} lista de cadenas 
 * @returns La cadena más corta
 */
function masCorta(cadenas){
    let corta=cadenas[0];
    for(let cadena of cadenas){
        if (cadena.length<corta.length){
            corta=cadena;
        }
    }
    return corta;
}

console.log(masCorta(["hola","que","pasa"])); // "que"
console.log(masCorta(["patatas","traigo","al","mercado"])); // "al"

Iterables

let notas = [3, 7, 4, 8, 6, 5, 9, 2];

// con forEach recorremos todos los valores del array
notas.forEach(function (valor) {
    console.log(valor);
})
let suma = 0;
notas.forEach(function (valor) {
    suma += valor;
})
console.log(suma)

// Imprimir las notas que están posiciones pares
notas.forEach(function (valor, indice) {
    if (indice % 2 == 0) {
        console.log(valor);
    }
})

// Puedo usar una función que ya exista
notas.forEach(mostrar);

function mostrar(valor) {
    console.log(valor);
}

let notasDuplicadas = notas.map(function (valor) {
    return valor * 2;
})
console.log(notas);
console.log(notasDuplicadas);

let notasMitad = notas.map((valor) => valor / 2);
console.log(notas);
console.log(notasMitad);

let copia = notas.map(valor => valor);
console.log(copia);

// Yo puedo usar filter para recuperar todos los elementos que cumplan una condición
let aprobados = notas.filter(function (valor) {
    return valor >= 5;
}
);
console.log(aprobados);

let suspendidos = notas.filter(valor => valor < 5);
console.log(suspendidos);

let suspensos = [];
for (let nota of notas) {
    if (nota < 5) {
        suspensos.push(nota);
    }
}
console.log(suspensos);

// Sumar todos los elementos de un array
let totalNotas = notas.reduce(function (total, valor) {
    return total + valor;
})
console.log(totalNotas)

// Suma todas las notas aprobadas
totalNotas = notas.reduce(function (total, valor) {
    if (valor >= 5) { total += valor; }
    return total;
})
console.log(totalNotas)
// Contar todas las notas aprobadas
totalNotas = notas.reduce(function (total, valor) {
    if (valor >= 5) { total++; }
    return total;
}, 0); // Le pongo 0 a total como valor inicial
console.log(totalNotas)

Iteraciones y paso por valor y por referencia

let notas = [3, 7, 4, 8, 6, 5, 9, 2];

// con forEach recorremos todos los valores del array
notas.forEach(function (valor) {
    console.log(valor);
})
let suma = 0;
notas.forEach(function (valor) {
    suma += valor;
})
console.log(suma)

// Imprimir las notas que están posiciones pares
notas.forEach(function (valor, indice) {
    if (indice % 2 == 0) {
        console.log(valor);
    }
})

// Puedo usar una función que ya exista
notas.forEach(mostrar);

function mostrar(valor){
    console.log(valor);
}

let notasDuplicadas=notas.map(function(valor){
    return valor*2;
})
console.log(notas);
console.log(notasDuplicadas);

let notasMitad=notas.map((valor)=>valor/2);
console.log(notas);
console.log(notasMitad);

let numeros=[1,2,3];
let ndoble=duplicar(numeros);
console.log(ndoble);
console.log(numeros)

let juanito=numeros; // Esto no es una copia del array
juanito[1]=17; // Si modifico el array nuevo modifico el original
console.log(numeros) // numeros ha cambiado

// Esta función me está modificando el array que le pasamos
// Esto ocurre porque los arrays se pasan por referencia
function duplicar(tabla){
    for(let i=0;i<tabla.length;i++){
        tabla[i]*=2;
    }
    return tabla;
}


let a=3;
let b=doble(a);
console.log(a)
console.log(b)

function doble(numero){
    numero*=2;
    return numero;
}

let notas=[1,2,3,4,5];

let suma=sumaTabla(notas);
console.log(suma); // Esto lo hace bien
console.log(notas); // Pero destruye el array original

// Esto me suma el array pero lo destruye
function sumaTabla(tabla){
    let suma=0;
    while(tabla.length>0){
        suma+=tabla.pop();
    }
    return suma;
}

function sumaTablaSinDestruir(tabla){
    // Antes de modificar el array hago una copia del mismo
    let copia=[...tabla];
    let suma=0;
    while(copia.length>0){
        suma+=copia.pop();
    }
    return suma;
}

Buscar en arrays

let notas=[3,6,2,7,3,9,10,8];

console.log(notas.includes(8)); // true porque hay un 8 en el array
console.log(notas.includes(5)); // false porque no hay ningún 5 en el array

let pos=notas.indexOf(7); // el 7 está en la posición 3
console.log(pos)

let pos2=notas.indexOf(5); // -1 porque no está
console.log(pos2)
pos=notas.indexOf(3);
console.log(pos); // 0 porque está en la posición 0
pos=notas.indexOf(3,1); // Busca a partir de la posición 1
console.log(pos); // 4 porque el siguiente 3 está en la posición 4

let numeros=[1,2,3,1,4,3,1,5,6,1];

// Buscar todas las posiciones donde está el  número 1
pos=numeros.indexOf(1); // Busco el número 1 desde el comienzo
while(pos!=-1){
    console.log(pos);
    pos=numeros.indexOf(1, pos+1); // busco el siguiente, diciendo que busque a partir de la siguiente posición
}

// En find no buscamos un valor, usamos una función

let aprobado=numeros.find(buscarAprobado); // Busca el primer elemento para el que esta función es true
console.log(aprobado)

function buscarAprobado(valor){
    return valor>=5;
}

let alumnos=["Ana","Eva","Pep","Juan"];

let al=alumnos.find(function(valor){
    return valor.toLocaleLowerCase().startsWith("p");
})
console.log(al);
al=alumnos.find((valor)=>valor.toLowerCase().endsWith("a"));
console.log(al)

let mates=[22,6,12,21,7,90];
console.log(mates.find(esPrimo));

function esPrimo(numero) {
    for (let i = 2; i < numero; i++) {
        if (numero % i == 0) {
            return false;
        }
    }
    return true;
}

let n=mates.find(function(valor,indice,array){
    console.log(valor,indice,array);
    // Quiero buscar el primer elemento que es menor que el siguiente
    if (valor<array[indice+1]){
        return true;
    }
})
console.log(n)

Ejemplos métodos arrays

let alumnos=["ana","pep","eva"];

// Añadimos un elemento al principio del array
alumnos.unshift("joan");
console.log(alumnos)

// Quitamos un elemento del principio del array
let alumno=alumnos.shift();
console.log(alumno);
console.log(alumnos);

console.log(alumnos.toString());
console.log(alumnos.join(" - "));

// at tiene el mismo comportamiento que en las cadenas y permite negativos
console.log(alumnos.at(1)) // alumnos[1]
console.log(alumnos.at(-1)) // alumnos[alumnos.length-1]

// NO USAR
delete alumnos[1];
console.log(alumnos);

let otrosAlumnos=["Juan","Marta","Maria"]
let aula=alumnos.concat(otrosAlumnos);
console.log(aula)

// Obtener partes de un array igual que en las cadenas (Obtener)
let nuevo=aula.slice(3,5);
console.log(nuevo)
console.log(aula)

let numeros=[1,2,3,4,5,6,7,8,9,10];

// Utilizamos splice para muchas cosas, veamos un ejemplo de cada una (modificar)
// Eliminar elementos en cualquier posición
let res=numeros.splice(4,2); // En a posición 4 quita 2 elementos
console.log(numeros);
console.log(res);

// Insertar elementos en cualquier posición
numeros.splice(4,0,55,66); // En la posición 4 estoy metiendo los valores 55 y 66
console.log(numeros);

// Sustituir elementos
numeros.splice(4,1,999); // En la posición 4 cambio el valor que hay por 999
console.log(numeros);

// Valores negativos
numeros.splice(-2,1,999); // En la posición penúltima cambio el valor que hay por 999
console.log(numeros);

// Parte el array en dos
let a=numeros.splice(4);
console.log(numeros,a)