Skip to content
Advertisement

How to print a nest list of map with Javascript

I have a function which converts a set of Javascript objects into a map. However, I get an object which cannot be navigated for its values; Here is the sample json

{
   "products":{
      "lemonade":{
         "product-type":"beverage",
         "product-details":{
            "calories":"129",
            "product-categories":[
               222,
               444
            ]
         }
      },
      "limeade":{
         "product-type":"beverage",
         "product-details":{
            "calories":"220",
            "product-categories":[
               222,
               444
            ],
            "salesIndex":{
               "percentage":1101,
               "demographics":"region-1"
            }
         }
      }
   }
}

Here is my function to convert to a map:

function objectToMap(o) {
  const m = new Map();
  console.log(`Processing for fragment ${fragment}`);
  for (const k of Object.keys(o)) {
    if (o[k] instanceof Object) {
      console.log(`Key is ${k} and object is ${JSON.stringify(o[k])}`);
      m.set(k, objectToMap(o[k]));
    } else {
      console.log(`Not an object ::Key is ${k} and object is
           ${JSON.stringify(o[k])}`);
      m.set(k, o[k]);
    }
  }
  return m;
}

Here is how I try to use and print the map:

const m1 = objectToMap(obj.products);
printMap(m1);

function printMap(map) {
  for (const k of map.keys()) {
    console.log(`Current key is ${k} and value is
${map.get(k)}`);
    if (map.get(k) instanceof Map) {
      printMap(map.get(k));
    } else {
      console.log(`No it is not a map :: Key is ${k} and value is ${map.get(k)}`);
    }
  }
}

However, I get for some this key, salesIndex, [object Map], why are the key, values not printed?

Advertisement

Answer

why are the key, values not printed?

They are printed, but the primitive values only get printed (later) when the object is passed to the recursive call, and there the else block is executed, i.e. when you arrive at the base case of the recursion.

Your code is fine, but you should avoid printing the value when you’re not yet at that base case, as that value still needs to be passed to the recursive call, which will take care of printing the deeper key/values.

I would suggest:

  • To only print the key (not the value) when the value is still an object
  • Print with indentation so it is much clearer what the structure is of the data
  • In objectToMap, support null values: for that you need to change the is-object test.

That’s the most important, but I’d also:

  • In objectToMap, use Object.entries instead of Object.keys so you get both the key and the value as your loop variables
  • Similarly, in printMap, use map.entries instead of map.values so you get both the key and the value as your loop variables
  • In objectToMap, as you call map.set() in both if and else cases, start with the call, and differentiate the argument with a conditional (ternary) operator

So like this:

// For the purpose of this answer, console.log removed from this function:
function objectToMap(o) {
  const m = new Map();
  for (const [k, v] of Object.entries(o)) { // Get both key and value
    // Use conditional operator and better way to check for objects:
    m.set(k, Object(v) === v ? objectToMap(v) : v);
  }
  return m;
}

// Extra argument for printing with indentation
function printMap(map, tab="") { 
  for (const [k, v] of map.entries()) {
    // Don't print here yet...
    if (v instanceof Map) {
      console.log(`${tab}${k}:`); // Only print the key here...
      printMap(v, tab + "    "); // ...as recursion will take care of the value(s)
    } else {
      console.log(`${tab}${k} = ${v}`);
    }
  }
}

// demo
const obj = {"products":{"lemonade":{"product-type":"beverage","product-details":{"calories":"129","product-categories":[222,444]}},"limeade":{"product-type":"beverage","product-details":{"calories":"220","product-categories":[222,444],"salesIndex":{"percentage":1101,"demographics":"region-1"}}}}};

const m = objectToMap(obj.products);
printMap(m);
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement