<span id="local->ethernet->port3->rx_flow">q4234</span>
<span id="local->ethernet->port3->rx">q345</span>
<span id="local->ethernet->port1->rx_flow">128</span>
<span id="remote->id">128</span>

and I need to make multidimensional array from them by ID example from element <span id="local->ethernet->port3->rx_flow">q4234</span>

array I need is array["local"]["ethernet"]["port3"]["rx_flow"]="q4234"

function I created is:

    function make_cfg(){
    var result=new Array();
    var x=document.getElementById(*);
    var len=x.length;
    var arr;
    for (var i=0; i<=len; i++;){
        if(x[i].id){
        if(x[i].id.indexOf("->") != -1) {
            arr=x[i].id.split("->");

            result=make_obj(result,arr);

        }
        }
    }
    return result;
    }

And I have no idea how to make function make_obj()

share|improve this question
2  
I suggest JSON instead – mplungjan May 20 '11 at 11:19
feedback

2 Answers

up vote 3 down vote accepted

I won't write the whole thing for you, I just help with the hard part a bit.

This snippet will take the two strings (basically id and innerHTML, here s and s2) and construct a nested object (there are no associative arrays in Javascript) out of it.

var s='local->ethernet->port3->rx_flow',
    s2='q4234',
    a=s.split('->'),
    obj=constructObject(a, s2);

function constructObject(a, final) {
    var val=a.shift();
    var obj={};
    if (a.length>0) {
        obj[val]=constructObject(a, final);
    } else {
        obj[val]=final;
    }
    return obj;
}

It uses recursion to achieve its goal. If you have any questions about the code, please ask.

Here you can try it out.

What is left to do?

I guess you want to collect these things from the spans into ONE object, my example will create one object for every s / s2. If you have any further questions, I am happy to help.

share|improve this answer
what is missing from my answer? Thanks – mplungjan May 20 '11 at 12:15
I did it function constructObject(a, final,obj) { var val=a.shift(); if (a.length>0) { if(!obj[val]){ obj[val]={}; } obj[val]=constructObject(a, final,obj[val]); } else { obj[val]=final; } return obj; } – crab May 20 '11 at 12:58
@crab Seems to be cool :). You could replace !obj[val] with !obj.hasOwnProperty(val) to be perfectly safe and have a nice code. – bažmegakapa May 20 '11 at 13:05
Thanks a lot @bazmegakapa there is an example how it works: jsfiddle.net/raimis/kCu4F – crab May 20 '11 at 13:15
Nice job @crab ! If you are satisfied with my answer, you can accept it with the tickmark on the left of the answer. – bažmegakapa May 20 '11 at 13:19
feedback

this almost worked (not so elegant as a recursive function)

http://jsfiddle.net/mplungjan/3zhwv/

Missing the 128 from the remote/id but the rest works. I would like to figure out what to do to get the 128 from the node that is shorter than 4

I agree it is not flexible like a recursive function, but I wanted to see if I could make a "brute force" first and then par it down to something more clever.

<span id="local->ethernet->port3->rx_flow">q4234</span>
<span id="local->ethernet->port3->rx">q345</span>
<span id="local->ethernet->port1->rx_flow">128</span>
<span id="remote->id">128</span>
<hr/>

<pre>
myObject = {
  "local":{
    "ethernet":{
       "port3": {
         "rx_flow":"q4234",
         "rx":"q345"
       } 
       "port1": {
         "rx_flow":"128"
       } 
    }
  },
  "remote":{
    "id":"128"
  } 
}
</pre>

<script>
var spans = document.getElementsByTagName("span");
var myObject = {};
for (var i=0;i < spans.length;i++) {
  var id = spans[i].id;
  var parts = id.split('->');
  var val = spans[i].innerHTML
  if (parts[0]) { // Local or remote
    if (myObject[parts[0]] == null) myObject[parts[0]]={};  
    if (parts[1]) { // ethernet or id
      if (myObject[parts[0]][parts[1]] == null) myObject[parts[0]][parts[1]]=(parts.length==1)?val:{};
      if (parts[2]) { // port3 or port1 
        if (myObject[parts[0]][parts[1]][parts[2]] == null) myObject[parts[0]][parts[1]][parts[2]]=(parts.length==2)?val:{};
        if (parts[3]) { // rx_flow or rx
          myObject[parts[0]][parts[1]][parts[2]][parts[3]]=val;
        }
      }
    }
  }    
}

for (var o in myObject) { // local or remote
  document.write(o+'/');
  for (var p in myObject[o]) { // ethernet or id
    document.write(p+'/');
    for (var q in myObject[o][p]) { // ports
      document.write(q+':/');
      for (var r in myObject[o][p][q]) { // rx_flow or rx
        document.write(r+' - '+myObject[o][p][q][r]+'<br/>');
      }
    }
  }
}
</script>
share|improve this answer
Hm, very hard to read and not quite flexible. What happens if you need to add another -> part? I haven't found where the exact problem is yet, not easy to analyze it. – bažmegakapa May 20 '11 at 12:47
I guess myObject[parts[0]] == null should be replaced by myObject.hasOwnProperty(parts[0]) (and all the similar ones). – bažmegakapa May 20 '11 at 12:52
@Baz please see update. I know it is not flexible, but I had to get my head around the structure first. the hasOwnProperty is not necessary. My script works except for "nodes" shorter than 4. I think I just need to test if the content is a string or object – mplungjan May 21 '11 at 5:00
feedback

Your Answer

 
or
required, but never shown
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.