Tengo una matriz de objetos javascript y estoy tratando de obtener una matriz de todos los valores únicos para una propiedad específica en cada objeto. Traté de hacer esto usando reduce (), mi código de ejemplo está a continuación, pero da como resultado un error que dice "No se pueden leer las propiedades de undefined (leyendo 'incluye')" aunque proporcioné un valor inicial de una matriz vacía. El resultado previsto es una matriz con
['New York', 'San Francisco', 'Chicago', 'Los Angeles']El objetivo final es crear un gráfico de barras con las ciudades en el eje X y el salario promedio calculado para cada ciudad en el eje Y, por lo que necesito la lista única de ciudades. ¿Hay alguna manera de evitar este error, o una mejor manera de hacer esto por completo?
const employees= [ {id: 0, city: 'New York', wagePerHour: '15'}, {id: 1, city: 'San Francisco', wagePerHour: '18'}, {id: 2, city: 'New York', wagePerHour: '16'}, {id: 3, city: 'Chicago', wagePerHour: '14'}, {id: 4, city: 'Chicago', wagePerHour: '12'}, {id: 5, city: 'San Francisco', wagePerHour: '15'}, {id: 6, city: 'New York', wagePerHour: '18'}, {id: 7, city: 'Los Angeles', wagePerHour: '10'} ]; const cities = employees.reduce((foundValues, nextEmployee) => { if(! foundValues.includes(nextEmployee.city)) { foundValues.push(nextEmployee.city); } }, []);Una forma aún más sencilla sería extraer todos los nombres de las ciudades y usar la función Establecer para crear una matriz única:
const employees = [{ id: 0, city: 'New York', wagePerHour: '15' }, { id: 1, city: 'San Francisco', wagePerHour: '18' }, { id: 2, city: 'New York', wagePerHour: '16' }, { id: 3, city: 'Chicago', wagePerHour: '14' }, { id: 4, city: 'Chicago', wagePerHour: '12' }, { id: 5, city: 'San Francisco', wagePerHour: '15' }, { id: 6, city: 'New York', wagePerHour: '18' }, { id: 7, city: 'Los Angeles', wagePerHour: '10' }] let cities = [... new Set(employees.map(x=>x.city))]; console.log(cities);Con Array#reduce tienes que devolver el valor previousValue actualizado. La forma más fácil de corregir su código es agregar return foundValues , que podría volver a escribir como:
const cities = employees.reduce((foundValues, nextEmployee) => foundValues.includes(nextEmployee.city) ? foundValues : foundValues.concat(nextEmployee.city), [] ); Sin embargo, puede explorar otros enfoques más eficientes, especialmente con el uso de Array#map y [...new Set()]
const employees= [ {id: 0, city: 'New York', wagePerHour: '15'}, {id: 1, city: 'San Francisco', wagePerHour: '18'}, {id: 2, city: 'New York', wagePerHour: '16'}, {id: 3, city: 'Chicago', wagePerHour: '14'}, {id: 4, city: 'Chicago', wagePerHour: '12'}, {id: 5, city: 'San Francisco', wagePerHour: '15'}, {id: 6, city: 'New York', wagePerHour: '18'}, {id: 7, city: 'Los Angeles', wagePerHour: '10'} ]; const cities = employees.reduce((foundValues, nextEmployee) => { if(!foundValues.includes(nextEmployee.city)) { foundValues.push(nextEmployee.city); } return foundValues; }, []); console.log( cities ); rewrite
const employees= [ {id: 0, city: 'New York', wagePerHour: '15'}, {id: 1, city: 'San Francisco', wagePerHour: '18'}, {id: 2, city: 'New York', wagePerHour: '16'}, {id: 3, city: 'Chicago', wagePerHour: '14'}, {id: 4, city: 'Chicago', wagePerHour: '12'}, {id: 5, city: 'San Francisco', wagePerHour: '15'}, {id: 6, city: 'New York', wagePerHour: '18'}, {id: 7, city: 'Los Angeles', wagePerHour: '10'} ]; const cities = employees.reduce((foundValues, nextEmployee) => foundValues.includes(nextEmployee.city) ? foundValues : foundValues.concat(nextEmployee.city), [] ); console.log( cities );Debe devolver el acumulador para la próxima iteración o como resultado.
const employees = [{ id: 0, city: 'New York', wagePerHour: '15' }, { id: 1, city: 'San Francisco', wagePerHour: '18' }, { id: 2, city: 'New York', wagePerHour: '16' }, { id: 3, city: 'Chicago', wagePerHour: '14' }, { id: 4, city: 'Chicago', wagePerHour: '12' }, { id: 5, city: 'San Francisco', wagePerHour: '15' }, { id: 6, city: 'New York', wagePerHour: '18' }, { id: 7, city: 'Los Angeles', wagePerHour: '10' }], cities = employees.reduce((foundValues, nextEmployee) => { if (!foundValues.includes(nextEmployee.city)) { foundValues.push(nextEmployee.city); } return foundValues; }, []); console.log(cities); Un enfoque más corto toma un Set con ciudades mapeadas para el constructor.
const employees = [{ id: 0, city: 'New York', wagePerHour: '15' }, { id: 1, city: 'San Francisco', wagePerHour: '18' }, { id: 2, city: 'New York', wagePerHour: '16' }, { id: 3, city: 'Chicago', wagePerHour: '14' }, { id: 4, city: 'Chicago', wagePerHour: '12' }, { id: 5, city: 'San Francisco', wagePerHour: '15' }, { id: 6, city: 'New York', wagePerHour: '18' }, { id: 7, city: 'Los Angeles', wagePerHour: '10' }], cities = Array.from(new Set(employees.map(({ city }) => city))); console.log(cities);