ServiceNow IC2 | HM Round Interview – JavaScript Deep Flatten + Type Grouping (with a Catch)

servicenow logo
servicenow
June 11, 20252 reads

Summary

I had a Hiring Manager round interview at ServiceNow, where I was presented with a challenging JavaScript problem involving deep flattening an array, grouping its elements by type, and counting the frequency of unique values within each type. I successfully navigated the problem, including debugging a runtime error and addressing several follow-up questions, which led to a positive outcome.

Full Experience

💼 HM Round Interview – JavaScript Deep Flatten + Type Grouping (with a Catch)


🔹 Part 1: Main Problem Asked

"You're given a deeply nested array with all kinds of values (numbers, strings, booleans, null, undefined, functions, symbols, objects).
Write a function that:

  • ✅ Deep flattens the array
  • ✅ Groups elements by their JavaScript typeof
  • ✅ Tracks the frequency count of each unique value within that type (This was the followup of the main question)

🔸 Sample Input:

const input = [1, 'a', [true, ['b', undefined], [{} , null]], () => {}, Symbol('x')];

🔸 Expected Output:

{
  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 }
}

🔹 Part 2: Follow-Up Challenge – Runtime Error & Fix

While implementing this, I hit a TypeError:

Cannot read properties of undefined (reading '1')


🐞 Root Cause:

if (!result[key]) {
  result[key] = {};
}

❌ Incorrect check — I was initializing based on key (the value),
but should have checked result[type] instead (the group).


✅ Corrected Code:

if (!result[type]) {
  result[type] = {};
}

🔍 Bonus Follow-Ups Asked:

  • 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.

✅ Outcome:

Handled edge cases, debugging, and recursion with safe typing and clean grouping logic.


Both versions of the solution:


✅ 1. With Frequency Count

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; }

🔸 Output Example:

{
number: { '1': 2 },
string: { 'a': 2, 'b': 1 },
boolean: { 'true': 2 },
undefined: { 'undefined': 1 },
null: { 'null': 1 },
symbol: { 'Symbol(x)': 2 }
}

✅ 2. Without Frequency Count (Just grouping by type)

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; }

🔸 Output Example:

{
number: [1, 1],
string: ['a', 'a', 'b'],
boolean: [true, true],
undefined: [undefined],
null: [null],
symbol: [Symbol('x'), Symbol('x')]
}

Interview Questions (1)

Q1
JavaScript Deep Flatten and Type Grouping with Frequency Count
Data Structures & Algorithms

You're given a deeply nested array with all kinds of values (numbers, strings, booleans, null, undefined, functions, symbols, objects).
Write a function that:

  • ✅ Deep flattens the array
  • ✅ Groups elements by their JavaScript typeof
  • ✅ Tracks the frequency count of each unique value within that type (This was the followup of the main question)

🔸 Sample Input:

const input = [1, 'a', [true, ['b', undefined], [{} , null]], () => {}, Symbol('x')];

🔸 Expected Output:

{
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 }
}

Discussion (0)

Share your thoughts and ask questions

Join the Discussion

Sign in with Google to share your thoughts and ask questions

No comments yet

Be the first to share your thoughts and start the discussion!