简体   繁体   English

使用JavaScript对JSON对象进行排序

[英]Sorting JSON objects with JavaScript

Okay. 好的。

I have a JSON object where each item of the object is a top level object...there are no nested relationships. 我有一个JSON对象,其中该对象的每个项目都是一个顶级对象...没有嵌套关系。 Some of the items are nested, but everything is top level. 有些项目是嵌套的,但所有内容都是顶级的。

The way a nested relationship is setup is by the ID value. 嵌套关系的设置方式是通过ID值。

  • Item a = item_a 项目a = item_a
  • Item b related to a = item_a.item_b 与a = item_a.item_b相关的项目b
  • Item c = item_c 项目c = item_c
  • Item d related to c = item_c.item_d 与c相关的项目d = item_c.item_d
  • Item e related to d = item_c.item_d.item_e 与d = item_c.item_d.item_e相关的项目e

I've tried splitting on the . 我已经尝试过拆分. and looping over the total json object and sorting them. 并遍历整个json对象并对其进行排序。 I've tried 4 or 5 different ways that I can think of and nothing is working properly. 我尝试了4种或5种我可以想到的不同方式,但没有任何工作正常。

What I am trying to end up with is a single object that looks like this. 我试图最终得到的是一个看起来像这样的单个对象。

Obj = [{
    item_a: {
        nestedItems: [{
            item_b: {}
        }]
    },
    item_c: {
        nestedItems: [{
            item_d: {
                nestedItems: {
                    item_e: {}
                }
            }
        }]
    }    
}];

I can not change the output so let's not ask that question. 我无法更改输出,所以我们不要问这个问题。 This is the problem I'm trying to solve. 这是我要解决的问题。 Can anyone help me understand the best way to sort this? 谁能帮助我了解整理此问题的最佳方法?

Here is my current state...but it's far from complete: 这是我目前的状态...但还远未完成:

function getNestedAttributes(attrs) // attrs is the JSON object
{
    var nested = [];

    for ( var i=0; i<attrs.length; i++ )
    {
        var idLevels = splitId(attrs[i].id); // split on . return array

        if ( idLevels.length == 1 )
        {
            nested[idLevels[0]] = attrs[i];
            nested[idLevels[0]]['nestedAttributes'] = [];
        }

        if ( idLevels.length > 1 )
        {
            nested[idLevels[0]]['nestedAttributes'].push(attrs[i]);
        }

    }

    console.log(nested);

}

The above is working to a point. 以上工作到了一定程度。 I'm making everything an array, which is fine, but it only works for objects that have one level nested. 我把所有东西都做成一个数组,这很好,但是它仅适用于嵌套了一个级别的对象。 Some items have up to 4 levels nested. 有些项目最多嵌套4个级别。

There has to be a better way to loop through this in JS. 在JS中必须有更好的方法来遍历此过程。

JSON: JSON:

attributes: [
{
    id: "item_a",
    name: "Item A Name",
    ...
},
{
    id: "item_a.item_b",
    name: "Item B Name",
    ...
},
{
    id: "item_a.item_c",
    name: "Item C Name",
    ...
},
{
    id: "item_d",
    name: "Item D Name",
    ...
},
{
    id: "item_d.item_e",
    name: "Item E Name",
    ...
},
{
    id: "item_d.item_e.item_f",
    name: "Item F Name",
    ...
}];

The above is a very basic example, but this is what the output looks like. 上面是一个非常基本的示例,但这就是输出的样子。

Ideally I'd end up with the following: 理想情况下,我将得到以下结果:

attributes: [
{
    id: "item_a",
    name: "Item A Name",
    nestedAttributes: [{
        id: "item_a.item_b"
        name: "Item B Name"
        ...
    },
    {
        id: "item_a.item_c"
        name: "Item C Name"
        ...
    }],
    ...
},
{
    id: "item_d",
    name: "Item D Name",
    nestedAttributes: [{
        id: "item_d.item_e"
        name: "Item E Name"
        nestedAttributes: [{
            id: "item_d.item_e.item_f",
            name: "Item F Name",
            ...
        }],
        ...
    }],
    ...
}];

Well, besides the obvious fact that this entire structure needs to be rethought and borders on schizophrenic, the answer is pretty straightforward. 好吧,除了显而易见的事实,整个结构都需要重新思考并与精神分裂症接壤,答案很简单。

Here's a jsfiddle that works . 这是一个工作的jsfiddle Essentially you just want to accumulate object, checking at each level, over the key elements. 本质上,您只想累积对象,在每个级别检查关键要素。

function build(attr) {
    var target, key, out = {},
        i = -1,
        len = attr.length;
    while (++i < len) {
        key = attr[i].id.split('.');
        target = makeOrFind(out, key);
        extend(target, attr[i]);
    }
    return out;
}

function makeOrFind(target, keyParts) {
    var key, i = -1, len = keyParts.length;
    while(++i < len) {
       key = keyParts[i];
        if( i > 0 ) {
           if( !target.nestedItems ) { target.nestedItems = {}; }
           target = target.nestedItems;
        }
       if( !target[key] ) { target[key] = {}; }
       target = target[key];
    }
    return target;
}

function extend(target, vals) {
   // this is an overly simple implementation of extend
   // it only works if your objects are exactly one level deep
   // but extend is a solved problem and not really in the scope of the question
    for( var key in vals ) {
        if( vals.hasOwnProperty(key) ) {
            target[key] = vals[key];   
        }
    }        
}

var out = build(attr);
console.log(out);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM