te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - Nested JSON Objects Within JSON Object - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Nested JSON Objects Within JSON Object - Stack Overflow

programmeradmin4浏览0评论

I'm trying to build a menu dynamically and I'm going to output the data to a JSON Object of the following form.

"Link 1": {
    "href":"#",
    "Sub Link 1": {
        "href":"#"
    },
    "Sub Link 2": {
        "href":"#",
        "Sub Sub Link 1": {
            "href":"#"
        },
        "Sub Sub Link 2": {
            "href":"#"
        }       
    }       
}

Firs of all, I'd like to know if that's a good design for a link hierarchy.

On the other hand, When I'm iterating over the array, I'm only able to get the name "Link 1" but not any of the properties underneath the link hierarchy.

The loop that I'm using is the following one:

for(var item in jsonMenu) {
    console.log(item)
}

It outputs: Link 1, Link 2, Link 3 but I want to be able to access the other JSON objects inside that object.

I tried nesting another loop but all I get are numbers : 0, 1, 2, 3 which I suspect is the length of the string.

I also tried using:

item.hasOwnProperty(key)

but it doesn't work: it returns Uncaught Reference Error: key does not exist

Any help would be greatly appreciated

EDIT:

This is so far what I have, but it seems to me like too much overhead for a menu, so far it has an execution time of O(n^2) and I still need to go one level deep, so the execution time would be of O(n^3):

 for(var item in jsonMenu) {
     if(jsonMenu.hasOwnProperty(item)) {
        for(var attr in jsonMenu[item]) {   
            console.log(attr);
        }
        console.log(item + " => " + jsonMenu[item])
    }
 }

I'm trying to build a menu dynamically and I'm going to output the data to a JSON Object of the following form.

"Link 1": {
    "href":"#",
    "Sub Link 1": {
        "href":"#"
    },
    "Sub Link 2": {
        "href":"#",
        "Sub Sub Link 1": {
            "href":"#"
        },
        "Sub Sub Link 2": {
            "href":"#"
        }       
    }       
}

Firs of all, I'd like to know if that's a good design for a link hierarchy.

On the other hand, When I'm iterating over the array, I'm only able to get the name "Link 1" but not any of the properties underneath the link hierarchy.

The loop that I'm using is the following one:

for(var item in jsonMenu) {
    console.log(item)
}

It outputs: Link 1, Link 2, Link 3 but I want to be able to access the other JSON objects inside that object.

I tried nesting another loop but all I get are numbers : 0, 1, 2, 3 which I suspect is the length of the string.

I also tried using:

item.hasOwnProperty(key)

but it doesn't work: it returns Uncaught Reference Error: key does not exist

Any help would be greatly appreciated

EDIT:

This is so far what I have, but it seems to me like too much overhead for a menu, so far it has an execution time of O(n^2) and I still need to go one level deep, so the execution time would be of O(n^3):

 for(var item in jsonMenu) {
     if(jsonMenu.hasOwnProperty(item)) {
        for(var attr in jsonMenu[item]) {   
            console.log(attr);
        }
        console.log(item + " => " + jsonMenu[item])
    }
 }
Share Improve this question asked May 2, 2013 at 17:45 ILikeTacosILikeTacos 18.7k20 gold badges61 silver badges93 bronze badges 5
  • Are you able to change the structure of your JSON? – Paul Commented May 2, 2013 at 17:47
  • Yes, I'm the one designing the JSON structure, if you have a better approach, I'd love to see it! – ILikeTacos Commented May 2, 2013 at 17:47
  • recursive loop the json data – rab Commented May 2, 2013 at 17:51
  • Recursively Traverse the JSON structure - stackoverflow./a/722676/1538708 – adamb Commented May 2, 2013 at 17:52
  • @AlanChavez I wouldn't get hung up on measuring plexity in javascript for generating a menu if I were you. Not saying it isn't important but throwing around Big 0 doesn't mean much if the set is really small – Matthew Cox Commented May 2, 2013 at 18:16
Add a ment  | 

5 Answers 5

Reset to default 4

If at all possible, I'd remend restructuring the source data so that the name is a property of the object rather than the key name itself, something like this:

{
    "name": "Link 1"
    "href":"#",
    "children": [
    {
        "name": "Sub Link 1"
        "href":"#"
    }       
}

This is better semantics, allows you to add additional properties easily and will be much easier to process and probably easier to generate too since it better matches an object in most programming languages. Otherwise you're left assuming every single key in an object is a new node.

Building on Paul's answer here is a function that renders this JSON as a Menu (demo):

<ul id='menu'></ul>
<script>
  var links = {
    "name": "Link 1",
    "href": "#link1",
    "children": [{
        "name": "Sub Link 1",
        "href": "#subLink1"
    }]
  },
  render = function (parent, link) {
    var element = $("<li><a href='" + link.href + "'>" + link.name + "</a></li>"),
        sublist,
        child;
    if (link.hasOwnProperty('children') && link.children.length > 0) {
        sublist = $("<ul></ul>");
        for (child = 0; child < link.children.length; child++) {
            render(sublist, link.children[child]);
        }
        element.append(sublist);
    }
    parent.append(element);
  };
  render($('#menu'), links);
</script>

I would reorganize your structure like so as to make it very easy to loop over and build the menu:

{
    "Links": [{
        "href": "#",
        "Links": [{
            "href": "#",
            "Links": [{ "href": "#" }, { "href": "#" }]
         }]
    }];
}

This will allow you to use a recursive looping approach where all the naming conventions are the same.

This seems like it would be perfect as a tree-like structure, where the text is a property and the value of the property is the inner text of the link. This is a much more flexible structure since you won't have to manually iterate over the properties of the object to find out the value of the inner text.

{ 
   text: "Link #1"
   href: "..."
   children: [{
      text: "Link #2",
      href: "...",
      children: []
   }, {
      text: "Link #3",
      href: "...",
      children: [{
          text: "Link #4",
          href: "...",
          children: []
      }]
   }]
}

Of course, this assumes that you will only ever have one root link. So if you want more, you can essentially have an array of "trees" like so:

[{ 
   text: "Link #1"
   href: "..."
   children: [{
      text: "Link #2",
      href: "...",
      children: []
   }, {
      text: "Link #3",
      href: "...",
      children: [{
          text: "Link #4",
          href: "...",
          children: []
      }]
   }]
}, {
   text: "Link #5",
   href: "...",
   children []
}, {
   text: "Link #6",
   href: "...",
   children: [{
      text: "Link #7",
      href: "...",
      children: []
   }]
}]

I don't think that schema is a good idea, for two reasons:

  • JSON objects are unordered - I guess you want to encode the order of submenus.
  • you can't have a submenu with with the title href (and maybe you later want to add other properties)

Better use arrays of objects, with a children property being another array. Iterating that is much easier also. Something like

{
    "name": "Link 1",
    "href":"#",
    "children": [{
        "name": "Sub Link 1",
        "href":"#"
    }, {
        "name": "Sub Link 2",
        "href":"#",
        "children": [{
            "name": "Sub Sub Link 1",
            "href":"#"
        }, {
            "name": "Sub Sub Link 2",
            "href":"#"
        }]
    }]
}
发布评论

评论列表(0)

  1. 暂无评论