I have an array of javascript objects and I am trying to get an array of all unique values for a specific property in each object. I tried to do this using reduce(), my example code is below, but it results in an error that it "Cannot read properties of undefined (reading 'includes')" even though I provided an initial value of an empty array. The intended result is an array with
['New York', 'San Francisco', 'Chicago', 'Los Angeles']
The end goal is to create a bar graph with the cities on the X-axis and the calculated average wage for each city on the Y-axis, so I need the unique list of cities. Is there a way to avoid this error, or a better way to do this altogether?
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);
}
}, []);
An even simpler way would be to extract all the cities names and use the Set function to build a unique array:
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);
With Array#reduce you have to return the updated previousValue. The easiest way to fix your code is to add return foundValues, which you could re-write as:
const cities = employees.reduce((foundValues, nextEmployee) =>
foundValues.includes(nextEmployee.city) ?
foundValues : foundValues.concat(nextEmployee.city), []
);
However, you're free to explore other more efficient approaches, especially with the use of Array#map and [...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 );
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With