2

我有一些 JSON 数据(简单的对象数组)。

var input= [
    {
        "cat": "some",
        "id": "0"
    },
    {
        "cat": "some",
        "id": "1"
    },
    {
        "cat": "some/category",
        "id": "2"
    },
    {
        "cat": "some/category/sub",
        "id": "3"
    },
    {
        "cat": "some/other",
        "id": "4"
    },
    {
        "cat": "some/thing/different",
        "id": "5"
    },
    {
        "cat": "some/thing/different",
        "id": "6"
    },
    {
        "cat": "yet/another",
        "id": "7"
    }
]

我想根据类别从中生成嵌套的 html 列表:

  • 一些
    • 0
    • 1
    • 类别
      • 2
        • 3
    • 其他
      • 4
    • 事物
      • 不同的
        • 5
        • 6
  • 然而
    • 其他
      • 7

我的第一步是使用该函数创建空的嵌套对象:

createNestedObject = function(base, names) {
  var  = 0;
  var results = [];
  while (i < names.length) {
    base = base[names[i]] = base[names[i]] || {};
    results.push(i++);
  }
  return results;
}

接下来,我通过拆分“cat”字符串并在循环中推送“ids”来填充数据(例如 some.category.sub.ids.push(7)),最终结果是:

var output = 
{
    "some": {
        "ids": [
            "0",
            "1"
        ],
        "category": {
            "ids": [
                "2"
            ],
            "sub": {
                "ids": [
                    "3"
                ]
            }
        },
        "other": {
            "ids": [
                "4"
            ]
        },
        "thing": {
            "different": {
                "ids": [
                    "5",
                    "6"
                ]
            }
        },
        "yet": {
            "another": {
                "ids": [
                    "7"
                ]
            }
        }
    }
}

但是,结构有些问题,因为我事先不知道键名和嵌套深度。如何从此处提供的“输出”或“输入”数据中生成嵌套的 html 列表?

4

4 回答 4

2

这个怎么样?

例子

JS

function ToHTML(input){
    var html = '<ul>'; 

    for(var key in input){
        if(input[key] instanceof Array){
            for(var i = 0; i < input[key].length; i++){
                html += '<li>' + input[key][i] + '</li>';
            }
        }else{
            html += '<li>' + key + ToHTML(input[key]) + '</li>';
        }           
    }
    html += '</ul>';
    return html; 
}

function ToNestedObject(input){
    var i, y, len = input.length, parts, partsLen, obj = {}, prev;
    for(i = 0; i < len; i++){
        parts = input[i].cat.split('/'); 
        partsLen = parts.length;
        prev = obj; 
        for(y = 0; y < partsLen; y++){
            prev[parts[y]] = prev[parts[y]] || {};    
            prev = prev[parts[y]];
        }
        if(!prev.ids){
            prev.ids = []; 
        }
        prev.ids.push(input[i].id); 
    }
    return obj; 
}

var input= [
    {
        "cat": "some",
        "id": "0"
    },
    {
        "cat": "some",
        "id": "1"
    },
    {
        "cat": "some/category",
        "id": "2"
    },
    {
        "cat": "some/category/sub",
        "id": "3"
    },
    {
        "cat": "some/other",
        "id": "4"
    },
    {
        "cat": "some/thing/different",
        "id": "5"
    },
    {
        "cat": "some/thing/different",
        "id": "6"
    },
    {
        "cat": "yet/another",
        "id": "7"
    }
];

document.getElementById('test').innerHTML = ToHTML(ToNestedObject(input)); 

HTML

<div id='test'></div>
于 2013-03-27T13:27:19.413 回答
1

由于您在标签下添加了 jquery,因此我已经在 jQuery 中编写了您的问题的解决方案。这是代码:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    </head>
<body>
    <div id="someDiv">
    </div>
    <script>

    function prepareNestedStructure(input) {
        var output = {},
            catLevels,
            currentCat;

        $.each(input, function(index, catObject) {
            catLevels = catObject.cat.split('/');
            currentCat = output;

            $.each(catLevels, function(index, name) {
                if(!currentCat[name])
                    currentCat[name] = {};
                currentCat = currentCat[name];
            });

            currentCat[catObject.id] = catObject.id;
        });

        return output;
    }

    function fillList(parentListEl, node) {
        $.each(node, function(key, value) {
            parentListEl.append('<li>' + key + '</li>');

            if(jQuery.type(value) === 'object') {
                var childEl = $('<ul></ul>');
                parentListEl.append(childEl);
                fillList(childEl, value);
            }
        });
    }

    var input= [
        {
            "cat": "some",
            "id": "0"
        },
        {
            "cat": "some",
            "id": "1"
        },
        {
            "cat": "some/category",
            "id": "2"
        },
        {
            "cat": "some/category/sub",
            "id": "3"
        },
        {
            "cat": "some/other",
            "id": "4"
        },
        {
            "cat": "some/thing/different",
            "id": "5"
        },
        {
            "cat": "some/thing/different",
            "id": "6"
        },
        {
            "cat": "yet/another",
            "id": "7"
        }
    ];

    var output = prepareNestedStructure(input);

    var ulDomElement = $('<ul></ul>');
    fillList(ulDomElement, output);
    $('#someDiv').append(ulDomElement);

    </script>
</body>
</html>
于 2013-03-27T14:45:23.423 回答
1

数组转换为对象树

function buildTreeObject ( input ) {

        var obj = {}, n ;

        input.forEach( function( v ){
                var keys = v.cat.split('/'),
                    n = obj ;        

                keys.forEach( function( k ){        
                        if ( !n[k]) {
                            n[k] = {}; 
                        }                 
                        n = n[k];                 
                }); 

                n[ v.id ] = v.id ;                
        });

        return obj;
}

我们需要一个函数来构建 html

function buildHtml( obj , ul ) {

    for (i in obj) {

        var li = document.createElement('li');
        li.innerHTML = i;
        ul.appendChild( li );

        if ( typeof(obj[i])== "object" ) {

            childUl = document.createElement('ul');
            li.appendChild( childUl ); 

            buildHtml(obj[i], childUl );            
        }  

    }
} 

并使用 html input(即你的数组)

var ul   = document.createElement('ul'),
    tree =  buildTreeObject( input ) ;

buildHtml( tree ,ul );

var div = document.createElement('div');    
div.appendChild( ul );

console.log( div.innerHTML );

打印所需的 ul li 列表

您可以在http://jsfiddle.net/r3RWL/中看到结果

于 2013-03-27T13:32:20.497 回答
0

那这个呢?

transform_deeply_nested_object = (dno) ->
    result = ""
    for key, value of dno
        if value instanceof Array
            result += "<ul>"
            for elem in value
                result += "<li>" + elem + "</li>\n"
            result += "</ul>"
        else
            result += "<ul><li>" + key + "</li>"
            result += transform_deeply_nested_object value
            result += "</ul>"

注意:未经测试!

注意:这要求所有叶子始终是数组的元素。

于 2013-03-27T13:03:57.210 回答