skip to Main Content

I have an flat object in javascript as

{
    top1: {
        obj1: {}
        obj2: {}
    }
    top2: {
        obj3: {}
        obj4: {}
    }
    top3: {
        obj5: {}
        obj6: {}
    }
}

and I would need to get out an array like

["top1","obj1"],["top1","obj2"],["top2","obj3"],["top2","obj4"],["top3","obj5"],["top3","obj6"]

I felt I could run a run a map as Object.keys(OBJ).map((key) => … but I ended in nothing.
Which method could be the best on this case?

3

Answers


  1. You could take a flat map approach with entries and their keys.

    const
        data = { top1: { obj1: {}, obj2: {} }, top2: { obj3: {}, obj4: {} }, top3: { obj5: {}, obj6: {} } },
        result = Object
            .entries(data)
            .flatMap(([k, o]) => Object.keys(o).map(l => [k, l]));
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    If you have deeper nested objects, you could take a recursive approach.

    const
        getKeys = object => Object
            .entries(object)
            .flatMap(([k, v]) => {
                if (!v || typeof v !== 'object') return [[k]];
                const nested = getKeys(v);
                return nested.length
                    ? nested.map(a => [k, ...a])
                    : [[k]];
            }),
        data = { top1: { obj1: {}, obj2: {} }, top2: { obj3: {}, obj4: {} }, top3: { obj5: {}, obj6: { obj7: {} } } },
        result = getKeys(data);
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }
    Login or Signup to reply.
  2. One-liner:

    Object.keys(o).flatMap(k => Object.keys(o[k]).map(K => [k, K]));
    

    Reference: Array#flatMap()

    Login or Signup to reply.
  3. Probably unnecessary non-recursive approach for unknown depth of nesting:

    const data = {
      top1: { obj1: {}, obj2: {} }, top2: { obj3: {}, obj4: {} }, top3: { obj5: {}, obj6: {} },
      top4: { mid1: { obj7: 'Three', obj8: 10 }, mid2: { obj9: null, obj10: [4, 5, 6] } }
    };
    
    const has_keys = (value) =>
      value && typeof value === 'object' && !Array.isArray(value) && Object.keys(value).length > 0;
    
    const get_routes = (data) => {
      const result = [];
      const queue = [[[], data]];
      
      while(queue.length > 0) {
        const [keys, value] = queue.pop();
        
        if(has_keys(value)) {
          queue.push(...Object.entries(value).map( ([k, v]) => [[...keys, k], v] ));
        } else {
          result.push(keys);
        }
      }
      
      return result.reverse();
    };
    
    console.log(get_routes(data));
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search