1

I have an an object I need to transform into a different format

The original:

{"module1":{"mod1":[{"hours":10},{"weeks":2},{"days":15}]},
 "module2":{"mod2":[{"cars":1},{"cats":5},{"people":4}]},
}

the desired result :

{"module1":"/mod1/10/2/15","module2":"/mod2/1/5/4" }

Here is my attempt (sorry im still learning this)

  function(newUrl){
            var encodedUrl = {};
            var tempString = "";
            console.log(JSON.stringify(newUrl));
             for (var p in newUrl) {

                    tempString = "/" + Object.keys(newUrl[p]);

               for (var j in newUrl[p]){
                    _.each(newUrl[p][j], function(obj){
                        tempString += "/" + _.values(obj);
                    });
                    encodedUrl[p] = tempString;
                    console.log(encodedUrl);
               }

             }

        }

So, I think i was able to make the string correctly. Hoever it only seems to be working the first time around. it's logging in a weird pattern

 Object {module1: "/mod1/10/2/15"}
 Object {module1: "/mod1///"}
 Object {module1: "/mod1///", module2: "/mod2/1/5/4"}

I think i have something wrong in my logic parsing this, I cannot pinpoint it though. Would love a second pair of eyes to help. Thanks!

1
  • Did you set up the original object or someone else's and your trying to manipulate it? Commented Mar 11, 2015 at 3:20

2 Answers 2

2

You have to loop over the properties of each object in turn, extracting the property names and values. There is also an array, so you have to loop over that too.

4 nested loops.

function  transformObj(obj) {

  var tObj, tStr, tArr, aObj, result = {};

  // For each own property in the object, e.g. 'module1'
  for (var p in obj) {
    if (obj.hasOwnProperty(p)) {

      // Transorm the value
      tObj = obj[p];
      tStr = '';

      // For each property in that object, e.g. 'mod1'
      for (var q in tObj) {
        if (tObj.hasOwnProperty(q)) {
          tStr = '/' + q;

          tArr = tObj[q];

          // for each member of the array
          for (var i=0, iLen=tArr.length; i<iLen; i++) {
            aObj = tArr[i]

            // for each property of each member, e.g. hours, weeks days
            for (var r in aObj) {
              if (aObj.hasOwnProperty(r)) {
                tStr += '/' + aObj[r];
              }
            }
          }
        }
      }

      // Assign transformed value to result object
      result[p] = tStr;
    }
  }
  return result;
}

var obj = {"module1":{"mod1":[{"hours":10},{"weeks":2},{"days":15}]},
           "module2":{"mod2":[{"cars":1},{"cats":5},{"people":4}]},
          };

console.log(JSON.stringify(transformObj(obj))); 

// {"module1":"/mod1/10/2/15","module2":"/mod2/1/5/4"}

You can replace the for..in and hasOwnProperty parts with Object.keys(...).forEach(...) to reduce the code a bit, but likely increase the complexity.

Note that the order that properties are returned by for..in and Object.keys will be the same but perhaps not necessarily as you expect, and may be different from browser to browser, so you can only expect consistent results when each object has one property.

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

1 Comment

Thank you for taking the time to explain :). Very helpful!
1

There's probably a shorter way, but it seems that your object is sort of complex.

Object.keys(obj).reduce(function(newObj, key, index) {
    var module = obj[key];
    var moduleKey = 'mod' + (index+1);
    var arr = module[moduleKey].map(function(o){return o[Object.keys(o)[0]]}).join('/');
    newObj[key] = "/" + moduleKey + "/" + arr
    return newObj
}, {});

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.