2

I haven't been learning JS for a long time, so I don't really understand how the stack and recursion work yet. The task is to display an array of object keys, and if the object is nested, then display not only the name of the key, but also the name of the parent object.

For example, we have an object:

{
    a: {
        b: 2,
        q: [0, 3, 4],
    },
    x: true,
    d: { f: null,
         c: 'something' 
        }
}

So, goal is to return an array of keys:

[
  'a.b',   'a.q',
  'a.q.0', 'a.q.1',
  'a.q.2', 'x',
  'd.f',   'd.c'
]

As you can see, nested keys need to have a fully qualified name, including the parent name separated by a dot.

I solved this problem, but with a huge nesting of conditional statements and loops, and specifically for this object. That is, if you add one more nesting, the function will not work.

function getKeysArray(obj) {
    let array = [];
    for (const key of Object.keys(obj)) {
        if (typeof obj[key] !== 'object') {
            array.push(key);
        }
        let internObj = obj[key];
        
        if (typeof internObj === 'object') {
            for (const innerKey of Object.keys(internObj)) {
                array.push(`${key}.${innerKey}`);
                let mostInnerKey = internObj[innerKey];

                if (typeof mostInnerKey === 'object' && internObj[innerKey] !== null) {
                    for (const index of Object.keys(mostInnerKey)) {
                        array.push(`${key}.${innerKey}.${index}`)
                    }
                }
            }
        }
    }
    return array;
}

I believe that you can solve this problem using recursion, I solved a similar problem, but it was necessary to display the values, not the keys, and it was solved quite simply.

How to solve this with recursion - I do not know.

I also saw solutions to similar problems on StackOverflow, but it was not necessary to display the full name of the keys this way.

0

2 Answers 2

3

You could take a recursive approach and have a look to objects.

const
    getPathes = o => Object
        .entries(o)
        .flatMap(([k, v]) => v && typeof v === 'object'
            ? getPathes(v).map(p => `${k}.${p}`)
            : k
        ),
    data = { a: { b: 2, q: [0, 3, 4] }, x: true, d: { f: null, c: 'something' } },
    pathes = getPathes(data);

console.log(pathes);

Sign up to request clarification or add additional context in comments.

1 Comment

Wow, this is amazing, I don't understand everything yet, but it looks so short, thanks a lot
1

const data = {"a":{"b":2,"q":[0,3,4]},"x":true,"d":{"f":null,"c":"something"}}

const f = (x, prefix='') =>
  Object.entries(x).flatMap(([k,v])=>[
    ...(Array.isArray(v) || !(v instanceof Object)) ? [`${prefix}${k}`]:[],
    ...v instanceof Object ? f(v, `${prefix}${k}.`):[]
  ])

console.log(f(data))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.