Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

286
Views
Javascript recursive function on nested object

We have the following kind of object:

const obj = {
    a: { "=": 0 },
    b: {
        c: { "=": 1 },
        d: {
            e: { "=": 2 },
            f: {
                g: { "=": 3 }
            }
        }    
    }

}

I am trying to write a function that returns an array with the object keys, including the nested ones, but groups them if they are nested and their values is not { "=": "something" }. To better explain I'll write a sample output desired for the object above:

["a", "b.c", "b.d.e", "b.d.f.g"]

All I have achieved for now is a function that only traverses the first level, but I admit I got stuck on the recursive part where the same function will apply on every level of the object until it reaches an entry of type { "=": "something" }. Follows my actual code:

function nestedObject(obj) {
    const operator = "="
    const attributes = []
    void (function traverse(obj) {
        if (isObject(obj)) { // <-- isObject(obj) just checks if typeof obj == "object", !Array.isArray(obj), obj !== null
            for (const [k,v] of Object.entries(obj)) {
                let attr = k
                for (const [k_,v_] of Object.entries(v)) {
                    if (operator !== k_) {
                        attr += "." + k_
                        // here is where the recursive part should start 
                        // but I didn't figure out yet how to make it right. 
                        // Of course calling traverse(v_) doesn't give the desired result.
                    }
                    attributes.push(attr)
                }
            }
        }
    })(obj)
    console.log(attributes) // <-- will output ["a", "b.c", "b.d"]
}

I hope I did explain well enough. I don't even know if this is possible, but I think it is. Would love to hear some ideas.

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

I keep handy some utility functions to make such coding easier. One of them takes an object and lists all the leaf paths in that object, as an array of keys. Building your function atop that becomes simply a matter of removing trailing = parts and joining the results with dots:

const getPaths = (obj) =>
  Object (obj) === obj
    ? Object .entries (obj) .flatMap (([k, v]) => getPaths (v) .map (p => [k, ...p]))
    : [[]]

const nestedObject = (obj) =>
  getPaths (obj) 
    .map (p => p .at (-1) == '=' ? p .slice (0, -1): p)
    .map (p => p .join ('.'))

const obj = {a: {"=": 0}, b: {c: {"=": 1}, d: {e: {"=": 2}, f: {g: {"=": 3}}}}}

console .log (nestedObject (obj))

This is a slightly less sophisticated version of getPaths than I usually write. Usually I distinguish between numeric array indices and string object keys, but that's not relevant here, so this version is simplified.

The main function should be clear enough on top of that.

Note that this does not prohibit internal = keys, so if, parallel to g in your input, you also had an h with an = key, like this:

            f: {
                g: { "=": 3 },
                h: { "=": {i: { "=": 4}}}
            }

we would yield this result:

["a", "b.c", "b.d.e", "b.d.f.g", "b.d.f.h.=.i"]

If you also wanted to remove those, you could add this between the two map calls:

    .filter (p => ! p.includes ('='))
about 4 years ago · Juan Pablo Isaza Report

0

Here's a small generator function that, given an object, recursively yields pairs like [ array-of-nested-keys, value ]:

function* enumRec(obj, keys=[]) {
    yield [keys, obj];
    if (obj && typeof obj === 'object')
        for (let [k, v] of Object.entries(obj))
            yield *enumRec(v, keys.concat(k))
}

To solve the problem at hand, iterate enumRec and collect keys that end with a =:

for (let [keys, _] of enumRec(obj)) {
    if (keys.at(-1) === '=')
        console.log(keys.slice(0, -1).join('.'))
}
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!