sivann
sivann

Reputation: 2131

rearrange javascript object

I have an object with depth at most 3:

OBJ.T.V.E={...}

T and V are integers (like in OBJ[0][1]['String']={...} ) so a typical structure could be:

OBJ[0][0]['S1']={..}
OBJ[0][0]['S2']={..}
OBJ[0][1]['S1']={..}
OBJ[0][2]['S1']={..}

I want to rearrange and get somehow this:

OBJNEW['S1'][0][0]={...}

which would have the same value as in OBJ[0][0]['S1']

I'm struggling for hours with no luck. Any ideas? Jquery code is also welcome.

EDIT: Right now I tried creating an array of objects like that:

OBJ2=[];
$.each(OBJ, function(name, value) {
  $(value).each(OBJ, function(name1, value1) {
    OBJ2[name1]=[];
    $(value1).each(OBJ, function(name2, value2) {
      OBJ2[name1][name2]={};
      OBJ2[name1][name2]['S1']={};
    })
  })

But this step fails since each ...['S1'] assignment overwrites the previous object (e.g. S2).

Please ignore any typos, I have just recreated the logic.

Upvotes: 1

Views: 2564

Answers (2)

Merlyn Morgan-Graham
Merlyn Morgan-Graham

Reputation: 59111

Some of the problem in your original code is that you can't use a plain array [] as an associative array {}. String keys can only be used in an associative array. The next problem is that you can and should iterate over all your string keys instead of trying to hard-code them.

The simplest thing you can do is write for/in loops for each level of your original object's hierarchy, then flip the assignment when writing them to the new object. You'll also have to check if the parent keys exist, and if they don't, create them.

var NEWOBJ = {};

for (var outerKey in OBJ) {
  for (var innerKey in OBJ[outerKey]) {
    for (var stringKey in OBJ[outerKey][innerKey]) {
      NEWOBJ[stringKey] = NEWOBJ[stringKey] || {};
      NEWOBJ[stringKey][outerKey] = NEWOBJ[stringKey][outerKey] || {};
      NEWOBJ[stringKey][outerKey][innerKey] = OBJ[outerKey][innerKey][stringKey];
    }
  }
}

console.log(NEWOBJ);​

As far as I know, jQuery will do little to nothing to help you here. It really isn't much simpler than the native Javascript that accomplishes the same thing.

Note that this doesn't do a deep copy of the objects you're moving around. I believe if you change objects in NEWOBJ that they'll also be changed in OBJ. I think it would be hard to solve this problem generically, and you'll probably have to resort to custom copy object for each object type.

Also note that I am not a Javascript GURU. I know there are sometimes problems when iterating over properties in an object that hasOwnProperty can solve that might creep up in an example like this. I don't know what those problems are off the top of my head, though. For example I tried this code with a simple JSON object and it worked :)

http://jsfiddle.net/e9uST/ - use the Javascript console in your browser to see the output.

Upvotes: 1

Tomalak
Tomalak

Reputation: 338208

This should get you pretty far, unless I misunderstood.

function flipObject(o) {
  var i1, i2, i3, result = {};

  for ( i1 in o ) {
    if ( o.hasOwnProperty(i1) ) {
      for ( i2 in o[i1] ) {
        if ( o[i1].hasOwnProperty(i2) ) {
          for ( i3 in o[i1][i2] ) {
            if ( o[i1][i2].hasOwnProperty(i3) ) {
              if ( !(i3 in result) ) result[i3] = {};
              if ( !(i1 in result[i3]) ) result[i3][i1] = {};
              result[i3][i1][i2] = o[i1][i2][i3];
            }
          }
        }
      }
    }
  }
  return result;
}

It turns

{
    "0": {
        "0": {
            "s1": "s1.0.0",
            "s2": "s2.0.0"
        },
        "1": {
            "s1": "s1.0.1",
            "s2": "s2.0.1"
        }
    },
    "1": {
        "0": {
            "s1": "s1.1.0",
            "s2": "s2.1.0"
        },
        "1": {
            "s1": "s1.1.1",
            "s2": "s2.1.1"
        }
    }
}

into

{
    "s1": {
        "0": {
            "0": "s1.0.0",
            "1": "s1.0.1"
        },
        "1": {
            "0": "s1.1.0",
            "1": "s1.1.1"
        }
    },
    "s2": {
        "0": {
            "0": "s2.0.0",
            "1": "s2.0.1"
        },
        "1": {
            "0": "s2.1.0",
            "1": "s2.1.1"
        }
    }
}

Upvotes: 3

Related Questions