-3

I have an object

   var tree = { 
                17:{
                  1:{
                     3:{},
                     4:{}
                    },
                  2:{
                     5:{},
                     6:{}
                   }
               }
           };

How to display the keys in this order 17, 1, 2, 3,4, 5,6 ?

i have tried this function:

var arr = [] ;
var arrObject = [] ;
function printValues(obj) {
    for (var key in obj) {
         arr.push(key);
        if (typeof obj[key] === "object") {
            arrObject.push(obj[key]);
            printValues(obj[key]);
        }
    }
}
printValues(tree);

the result is 17,1,3,42,5,6 . and i need 17, 1, 2, 3,4, 5,6

aharo vishinsky
  • 131
  • 1
  • 4
  • 12
  • `34` and `56` ??? – Pranav C Balan Jun 15 '17 at 09:35
  • Loop over them and push keys to an array and at the end you can directly call `array.join()`. But this will not handle `34,56`. For this you will need custom handling. We can suggest some tricks but for that we would need to see your code – Rajesh Jun 15 '17 at 09:36
  • Possible duplicate of [How to Loop through plain JavaScript object with objects as members?](https://stackoverflow.com/questions/921789/how-to-loop-through-plain-javascript-object-with-objects-as-members) – Hellium Jun 15 '17 at 09:37
  • 1
    Since the order of properties in an object is undefined, there's no guarantee they will be displayed like that, unless you specifically sort them, which you'd have to clarify. – deceze Jun 15 '17 at 09:37
  • I update my question, the result I am trying to get is 17, 1, 2, 3,4, 5,6; – aharo vishinsky Jun 15 '17 at 12:04

2 Answers2

1

The following uses a recursive function to extract all the nested keys associated with their depth in the object. It then sorts the results by depth.

Note that the approach may change the order of the keys at a given depth. To demonstrate this, I change the 3 in your example to 99. The returned results include "4", "99", not "99", "4". However, as pointed out in the comment by @deceze, the order of properties in an object is undefined anyway, so changing the order within a given object depth shouldn't (hopefully) be a problem. (If it is a problem then you need a different approach, e.g. using an array instead of an object.)

Note also that the code below returns an array of strings. This would be especially appropriate if some of your keys are explicitly strings, e.g. using letters. If you really want the results to be numerical, just add a + to the map command, i.e. ... .map(elmt => +elmt[1]).

const getKeysOrderedByDepth = obj => {
  let arr = [], level = 0;
  const getKeys = obj => {
    level += 1;
    for (let key in obj) {
      arr.push([level, key]);
      const val = obj[key];
      getKeys(obj[key]);
    }
    level -= 1;
  };
  getKeys(obj);
  return arr.sort((a, b) => a[0] - b[0]).map(elmt => elmt[1]);
};

let tree = {
  17: {
    1: {
      99: {},
      4: {}
    },
    2: {
      5: {},
      6: {}
    }
  }
};

console.log(getKeysOrderedByDepth(tree));
Andrew Willems
  • 11,880
  • 10
  • 53
  • 70
0

This is works for me(changed):


    const tree = {
      first:{
        1:{
          3:{
            7: 7,
            8: 8,
          },
          4:{
            9: 9,
            10: 10,
          }
        },
        2:{
          5:{
            20: {
              30: 30,
            },
            21: {
              31: 31,
            }
          },
          6:{
            22: 22,
          }
        },
      },
    };

    const keys = [];

    /**
     * Handle merged values
     * @param values
     */
    function handleData(values) {
      let subValues = {};
      for (let key in values) {
        keys.push(key);
        Object.assign(subValues, handle(values[key]));
      }
      // If have values, handle them
      if (Object.keys(subValues).length) handleData(subValues);
    }

    /**
     * Handle one value
     * @param value
     * @returns {{}}
     */
    function handle(value) {
      if (Object.keys(value).length) {
        return Object.assign({}, value);
      }
    }

    // Handle our data
    handleData(tree);

    console.log(keys); // ['first',1,2,3,4,5,6,7,8,9,10,20,21,22,30,31]

O. Borcuhin
  • 234
  • 2
  • 5
  • if I add another like this const tree = { 17:{ 1:{ 3:{}, 4:{} }, 2:{ 5:{7:7,8:8}, 6:{} } } }; so it still display ["17", "1", "2", "3", "4", "5", "6"] ; its need to be dynamic. every level print from the left to the right – aharo vishinsky Jun 15 '17 at 13:11