"You're given a deeply nested array with all kinds of values (numbers, strings, booleans, null, undefined, functions, symbols, objects).
Write a function that:
typeofconst input = [1, 'a', [true, ['b', undefined], [{} , null]], () => {}, Symbol('x')];{
number: { '1': 1 },
string: { 'a': 1, 'b': 1 },
boolean: { 'true': 1 },
undefined: { 'undefined': 1 },
null: { 'null': 1 },
object: { '[object Object]': 1 },
function: { '() => {}': 1 },
symbol: { 'Symbol(x)': 1 }
}While implementing this, I hit a TypeError:
Cannot read properties of undefined (reading '1')
if (!result[key]) {
result[key] = {};
}❌ Incorrect check — I was initializing based on key (the value),
but should have checked result[type] instead (the group).
if (!result[type]) {
result[type] = {};
}Why does typeof null === 'object'?
→ Legacy bug. I handled it using: item === null ? 'null' : typeof item.
How did you stringify symbols safely for keys?
→ Used item.toString() for Symbol(x) values.
What if you needed to keep raw values instead of string keys?
→ Suggested using a Map or { value, count } objects instead of stringified keys.
Handled edge cases, debugging, and recursion with safe typing and clean grouping logic.
Both versions of the solution:
function deepFlattenAndGroupByTypeWithFrequency(input) {
const result = {};
function recurse(arr) {
for (const item of arr) {
if (Array.isArray(item)) {
recurse(item); // handle nested arrays
} else {
const type = item === null ? 'null' : typeof item;
const key = typeof item === 'symbol' ? item.toString() : String(item);
if (!result[type]) {
result[type] = {};
}
result[type][key] = (result[type][key] || 0) + 1;
}
}
}
recurse(input);
return result;
}{
number: { '1': 2 },
string: { 'a': 2, 'b': 1 },
boolean: { 'true': 2 },
undefined: { 'undefined': 1 },
null: { 'null': 1 },
symbol: { 'Symbol(x)': 2 }
}function deepFlattenAndGroupByType(input) {
const result = {};
function recurse(arr) {
for (const item of arr) {
if (Array.isArray(item)) {
recurse(item);
} else {
const type = item === null ? 'null' : typeof item;
if (!result[type]) {
result[type] = [];
}
result[type].push(item);
}
}
}
recurse(input);
return result;
}{
number: [1, 1],
string: ['a', 'a', 'b'],
boolean: [true, true],
undefined: [undefined],
null: [null],
symbol: [Symbol('x'), Symbol('x')]
}