2
<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()

kapa
  • 77,694
  • 21
  • 158
  • 175
crab
  • 43
  • 4

2 Answers2

5

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.

kapa
  • 77,694
  • 21
  • 158
  • 175
  • 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. – kapa May 20 '11 at 13:05
  • Thanks a lot @bazmegakapa there is an example how it works: http://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. – kapa May 20 '11 at 13:19
0

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>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • 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. – kapa May 20 '11 at 12:47
  • I guess `myObject[parts[0]] == null` [should be replaced](http://stackoverflow.com/questions/135448/how-do-i-check-to-see-if-an-object-has-an-attribute-in-javascript) by `myObject.hasOwnProperty(parts[0])` (and all the similar ones). – kapa 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 05:00