使非规范化JSON分层

时间:2014-03-11 19:36:51

标签: javascript json

我正在使用非规范化的JSON结构,但是我需要嵌套的JSON在客户端的多个级别上迭代它们。我很难理解如何优雅地做到这一点。

您能想到如何轻松转换表单的JSON

[{ category: xyz, attribute: 1},{ category: xyz, attribute: 2}] 

采用分层格式:

[{category: xyz, attributes: [1,2]}] ?

非常感谢任何解决方案。

3 个答案:

答案 0 :(得分:1)

function reorder(arr) {
    var heir = {};
    arr.forEach(function(i){
        for (var j in i) {
            if (heir[j]) {
                if (heir[j].indexOf(i[j]) == -1) {
                    heir[j].push(i[j]);
                }
            } else {
                heir[j] = [i[j]];
            }
        }
    });
    for (var i in heir) {
        if (heir[i].length == 1) {
            heir[i] = heir[i][0];
        }
    }
    return heir;
}

这完全符合你的榜样,但非常接近:

{ category: 'xyz', attribute: [ 1, 2 ] }

答案 1 :(得分:1)

我一直这样做,虽然通常是在服务器端。代码看起来像这样:

function normalize(key, outputKey, data)
{
    var results = [];
    var record;

    for(var i=0; i<data.length; i++)
    {
        if(!record || record[key] != data[i][key])
        {
           record = {};
           record[outputKey] = [];
           record[key] = data[i][key];
           results.push(record);
        }

        delete data[i][key];
        record[outputKey].push(data[i]);
    }

    return results;
}

这是输出:

[
  {
    "category": "xyz",
    "values": [
      { "attribute": 1 },
      { "attribute": 2 }
    ]
  }
]

请注意,您的示例输出搞砸了。您可能想要决定是否尝试对数组的对象或值进行分组。后者更容易。

编辑:当然,您正在寻找无聊的答案。你走了:

function collapse(key, attr, data)
{
    var results = [];
    var record;

    for(var i=0; i<data.length; i++)
    {
        if(!record || record[key] != data[i][key])
        {
           record = data[i];
           record[attr] = [data[i][attr]];
           results.push(record);
        }
        else
        {
            record[attr].push(data[i][attr]);
        }
    }

    return results;
}

如果你这样称呼它:

var data = [{ category: 'xyz', attribute: 1},{ category: 'xyz', attribute: 2}];
collapse('category', 'attribute', data);

你会得到这个输出:

[{"category":"xyz","attribute":[1,2]}]

答案 2 :(得分:1)

当我必须做这样的事情时,我通常使用元数据构建外部数组以提高代码可读性。如果您的JSON很大,那就不要这样做。

function normalize(json) {
    var categories= [];
    var norm= [];
    for (var i=0; i < json.length; i++) {
         if (categories.indexOf(json[i].category) !== -1) {
              categories.push(json[i].category);
         }
    }
    for (var i=0; i < categories.length; i++) {
        norm.push({ category: categories[i]; attributes: []});
    }
    for (var i=0; i < json.length; i++) {
        norm[categories.indexOf(json[i].category)].attributes.push(json[i].attribute);
    }
    return norm;
}

我的答案是O(n * log(m)+ n + n * m),其中n是最外面的json的长度,m是类别的数量,但是n * log(m)和n * m是indexOf部分,它由浏览器在本机代码中完成。我太懒了,不能与其他答案进行适当的大O比较,但这显然比较慢。