I’m working on a JavaScript project where I generate a list of employees and their respective work hours. I want to create a chart data object with the names and values of employees, but when I log the chartData
, it outputs something like this:
chartData: {
all: [
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object]
]
}
Instead of the expected output, which should look like this:
chartData: {
all: [
{ label: 'Lukáš', value: 8 },
{ label: 'Eva', value: 8 },
{ label: 'Tomáš', value: 7 },
{ label: 'Anna', value: 6 },
{ label: 'Lucie', value: 5 },
{ label: 'Jan', value: 4 },
{ label: 'Petr', value: 4 },
{ label: 'Tereza', value: 3 },
{ label: 'Michal', value: 3 },
{ label: 'Jana', value: 2 }
]
}
I checked the nameCounter function, and it seems to be counting the names correctly.
I used Object.entries and .map to convert the counts to the required format.
I logged the result, but the output is still in the [Object], [Object]
format, which makes me think that the issue might be with how I’m logging the result or how the data is being returned.
heres my code:
// Array of male names
const maleNames = [
"Peter", "John", "Michael", "Luke", "Thomas"]
// Array of female names
const femaleNames = [
"Anna", "Jane", "Eva", "Lucy", "Teresa"]
// Array of male last names
const maleLastname = [
"Smith", "Johnson", "Brown", "Taylor", "Anderson"]
// Array of female last names
const femaleLastname = [
"Smith", "Johnson", "Brown", "Taylor", "Anderson"
]
/**
* Main function to generate a list of employees based on input parameters.
* @param {object} dtoIn - Input object with parameters.
* @param {number} dtoIn.count - The number of employees to generate.
* @param {object} dtoIn.age - The age range of the employees.
* @param {number} dtoIn.age.min - Minimum age of employees.
* @param {number} dtoIn.age.max - Maximum age of employees.
* @returns {Array<object>} - An array of objects representing the employees.
*/
function generateEmployeeData(dtoIn) {
const dtoOut = [];
for (let i = 0; i < dtoIn.count; i++) {
let gender = getGender(); // Randomly select gender
let employee = {
gender: gender,
birthdate: getBirthdate(dtoIn.age.min, dtoIn.age.max),
name: getName(gender, maleNames, femaleNames), // Get the name based on gender
surname: getName(gender, maleLastname, femaleLastname), // Get the surname based on gender
workload: getWorkload() // Randomly select workload
}
dtoOut.push(employee);
}
// Sort employees by their workload in ascending order
return dtoOut.sort((a, b) => a.workload - b.workload);
}
/**
* Randomly generates a number within the given range.
* @param {number} min - The minimum value.
* @param {number} max - The maximum value.
* @returns {number} - A random number between min and max (inclusive).
*/
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
/**
* Randomly determines the gender.
* @returns {string} - "male" or "female".
*/
function getGender() {
return getRandom(0, 1) === 0 ? 'male' : 'female';
}
/**
* Generates a random birthdate based on the given age range.
* @param {number} ageMin - Minimum age.
* @param {number} ageMax - Maximum age.
* @returns {string} - Birthdate in ISO 8601 format.
*/
function getBirthdate(ageMin, ageMax) {
const currentDay = new Date().getTime();
const yearInMil = 365.25 * 24 * 60 * 60 * 1000;
const minRange = currentDay - (new Date(ageMax * yearInMil));
const maxRange = currentDay - (new Date(ageMin * yearInMil));
const birthDate = getRandom(minRange, maxRange);
return new Date(birthDate).toISOString();
}
/**
* Returns a random name based on gender.
* @param {string} gender - Gender ("male" or "female").
* @param {Array<string>} male - Array of male names.
* @param {Array<string>} female - Array of female names.
* @returns {string} - A random name corresponding to the gender.
*/
function getName(gender, male, female) {
return gender === 'male' ? male[getRandom(0, male.length - 1)] : female[getRandom(0, female.length - 1)];
}
/**
* Generates a random workload (work hours) from a list of possible values.
* @returns {number} - Random workload (e.g., 10, 20, 30, 40).
*/
function getWorkload() {
const workloads = [10, 20, 30, 40];
const index = getRandom(0, workloads.length - 1);
return workloads[index];
}
/**
* Extracts all names from a list of employees.
* @param {Array<object>} list - List of employees.
* @returns {Array<string>} - Array of employee names.
*/
function getAllNames(list) {
return list.map(e => e.name);
}
/**
* Filters the list by gender and returns only employees of the specified gender.
* @param {Array<object>} list - List of employees.
* @param {string} gender - The gender to filter by ("male" or "female").
* @returns {Array<object>} - Filtered list of employees by gender.
*/
function getNameByGender(list, gender) {
return list.filter(e => e.gender === `${gender}`);
}
/**
* Filters the list by gender and workload (full-time or part-time).
* @param {Array<object>} list - List of employees.
* @param {number} [workload] - If provided, filters by a specific workload.
* @returns {Array<string>} - List of names that match the criteria.
*/
function genderWorkload(list, workload) {
if (workload === undefined) {
let femaleList = getNameByGender(list, "female");
femaleList = femaleList.filter(e => e.workload !== 40); // Part-time female employees
return getAllNames(femaleList);
}
else {
let maleList = getNameByGender(list, "male");
maleList = maleList.filter(e => e.workload === 40); // Full-time male employees
return getAllNames(maleList);
}
}
/**
* Counts the occurrences of names in a list.
* @param {Array<string>} list - List of names.
* @returns {object} - An object with the name counts.
*/
function nameCounter(list) {
return list.reduce((acc, name) => {
acc[name] = (acc[name] || 0) + 1;
return acc;
}, {});
}
/**
* Converts the name counts into the required format { label, value } and sorts by value.
* @param {Array<string>} list - List of names.
* @returns {Array<object>} - Array of objects with the format { label: name, value: count }.
*/
function charOutput(list) {
const countedNames = nameCounter(list);
return Object.entries(countedNames).map(([label, value]) => ({
label: label,
value: value
})).sort((a, b) => b.value - a.value); // Sort by value descending
}
/**
* Creates chart data with name counts for all employees, male, and female.
* @param {Array<object>} list - List of employees.
* @returns {object} - Object containing chart data for all employees, male and female.
*/
function getEmployeeChartContent(list) {
const dtoOut = {
names: {
all: nameCounter(getAllNames(list)), // Dynamic creation for 'all'
male: nameCounter(getAllNames(getNameByGender(list, "male"))),
female: nameCounter(getAllNames(getNameByGender(list, "female"))),
femalePartTime: nameCounter(genderWorkload(list)),
maleFullTime: nameCounter(genderWorkload(list, 40)),
},
chartData: {
all: charOutput(getAllNames(list)),
male: charOutput(getAllNames(getNameByGender(list, "male"))),
}
};
return dtoOut;
}
/**
* The main function to generate employee data and chart content.
* @param {object} dtoIn - Input parameters.
* @returns {void}
*/
function main(dtoIn) {
let data = generateEmployeeData(dtoIn);
const dtoOut = getEmployeeChartContent(data);
}
// Example input data for employee generation
const dtoIn = {
count: 50,
age: {
min: 19,
max: 35
}
}
// Generate employee data and display the chart content
let data = generateEmployeeData(dtoIn);
console.log(getEmployeeChartContent(data));
// Output the name count in the required chart format
console.log(charOutput(getAllNames(data)));
2
Answers
that console.log just prints the higher level values, if you want to print nestes objects (and arrays) too you should JSON.stringify() the log
Instead of
write
and the output will be not [Object Object], but will show all nested values
If you’re using runtimes like Node or Deno you can use
console.dir()
withdepth
option to pretty print nested objects: