In the real world, data is messy. Some fields are missing, some are empty, some have duplicates. Let's use our power-ups to clean up a messy list of sign-ups (the kind of thing that might come from an online form).
const signups = [
{ name: "Mia", email: "mia@example.com", age: 21, tags: ["music", "coding"] },
{ name: "Omar", email: "omar@example.com", age: 0, tags: ["sports", "coding"] },
{ name: "", email: "mystery@example.com", tags: ["coding", "art"] },
{ name: "Zoe", email: "mia@example.com", age: 34, profile: { city: "Lisbon" } },
{ name: "Sam", email: "sam@example.com", age: 19, tags: ["music"], profile: { city: "Paris" } },
];
// 1. Remove duplicate emails (keep the first one we see)
const seenEmails = new Set();
const unique = signups.filter(({ email }) => {
if (seenEmails.has(email)) return false;
seenEmails.add(email);
return true;
});
// 2. Fill in missing values with sensible defaults
const cleaned = unique.map(({ name, email, age, tags, profile }) => ({
name: name || "Anonymous", // empty name → "Anonymous"
email,
age: age ?? "unknown", // keep 0, replace missing
tags: tags ?? [],
city: profile?.city ?? "not given",
}));
console.log(`${signups.length} sign-ups → ${cleaned.length} after removing duplicates\n`);
for (const { name, age, city, tags } of cleaned) {
console.log(`${name.padEnd(10)} age: ${String(age).padEnd(8)} city: ${city.padEnd(10)} tags: ${tags.length}`);
}
// 3. Count interests across everyone, with a Map
const interestCounts = new Map();
for (const person of cleaned) {
for (const tag of person.tags) {
interestCounts.set(tag, (interestCounts.get(tag) ?? 0) + 1);
}
}
const allTags = [...interestCounts.keys()];
console.log(`\nAll interests: ${allTags.join(", ")}`);
for (const [tag, count] of interestCounts) {
console.log(` ${tag}: ${"★".repeat(count)}`);
}
It prints
5 sign-ups → 4 after removing duplicates Mia age: 21 city: not given tags: 2 Omar age: 0 city: not given tags: 2 Anonymous age: unknown city: not given tags: 2 Sam age: 19 city: Paris tags: 1 All interests: music, coding, sports, art music: ★★ coding: ★★★ sports: ★ art: ★
Look at all the power-ups at work:
- A
Settracks which emails we've already seen, so the duplicatemia@example.com(Zoe's entry) is removed. - Destructuring in parameters pulls out each field neatly.
||replaces the empty name with"Anonymous", because we want any falsy name replaced.??replaces only missing ages, so Omar's age of0is kept. (Using||here would have wrongly made Omar's age "unknown".)?.safely reaches intoprofile, which most people don't have.- A
Mapcounts the interests, and spread turns its keys into an array.
This is exactly the kind of code professional developers write every day when handling real-world data.
Add a few more messy sign-ups of your own (missing emails, weird ages, duplicate tags inside one person's list) and see if the cleaner handles them. Can you make it also remove duplicate tags within a single person's tags array? (Hint: [...new Set(tags)].)
🎓 CONGRATULATIONS! YOU'VE GRADUATED FROM HIGH SCHOOL! 🎓
Throw your cap in the air! You now know modern JavaScript: the fundamentals, the power tools, the DOM, events, and all the slick modern syntax. You can build real, interactive web pages.
And as promised, you've earned a full scholarship to our College. No essays, no applications. In College, you'll tackle the advanced topics that separate hobbyists from professionals: asynchronous code, classes, modules and tools, and finally, your capstone projects.