最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

javascript - How to convert flat multi-branch data to hierarchical JSON? - Stack Overflow

matteradmin5PV0评论
[
  {
    "id": "a",
    "pid": "a",
    "name": "AA",
  },
  {
    "id": "b",
    "pid": "a",
    "name": "BB",
  },
  {
    "id": "c",
    "pid": "a",
    "name": "CC",
  },
  {
    "id": "x",
    "pid": "b",
    "name": "XX",
  }
]

Above is the data I got from the database. Every person has an id and a pid, pid points to the person's higher level person's id. If a person has highest level, the id equals pid.

I want to convert the raw data to hierarchical JSON, like this:

[
  {
    "id": "a",
    "name": "AA",
    "child": [
      {
        "id": "b",
        "name": "BB"
        "child": [
          {
            "id": "x",
            "name": "XX"
          }
        ]
      },
      {
        "id": "c",
        "name": "CC"
      }
    ]  
  }
]

I'm using Node.js.

[
  {
    "id": "a",
    "pid": "a",
    "name": "AA",
  },
  {
    "id": "b",
    "pid": "a",
    "name": "BB",
  },
  {
    "id": "c",
    "pid": "a",
    "name": "CC",
  },
  {
    "id": "x",
    "pid": "b",
    "name": "XX",
  }
]

Above is the data I got from the database. Every person has an id and a pid, pid points to the person's higher level person's id. If a person has highest level, the id equals pid.

I want to convert the raw data to hierarchical JSON, like this:

[
  {
    "id": "a",
    "name": "AA",
    "child": [
      {
        "id": "b",
        "name": "BB"
        "child": [
          {
            "id": "x",
            "name": "XX"
          }
        ]
      },
      {
        "id": "c",
        "name": "CC"
      }
    ]  
  }
]

I'm using Node.js.

Share Improve this question edited Jun 14, 2016 at 8:30 RockerFlower asked Jun 14, 2016 at 8:03 RockerFlowerRockerFlower 7272 gold badges11 silver badges28 bronze badges 5
  • is the data sorted by id, or is it random ordered? – Nina Scholz Commented Jun 14, 2016 at 8:17
  • @NinaScholz It is random ordered, but IDs are unique. – RockerFlower Commented Jun 14, 2016 at 8:18
  • 1 how do you know the root of the tree? please add some more data for checking. – Nina Scholz Commented Jun 14, 2016 at 8:20
  • @NinaScholz When the id equals pid, he is the root. – RockerFlower Commented Jun 14, 2016 at 8:22
  • I updated the question, thank you!@NinaScholz – RockerFlower Commented Jun 14, 2016 at 8:30
Add a ment  | 

2 Answers 2

Reset to default 5

I suggest you to create a tree and take id === pid as a root for the tree, which works for unsorted data.

How it works:

Basically, for every object in the array, it takes the id for building a new object as parentid for a new object.

For example:

{ "id": 6, "pid": 4 }

It generates this property first with id:

"6": {
    "id": 6,
    "pid": 4
}

and then with pid:

"4": {
    "children": [
        {
            "id": 6,
            "pid": 4
        }
    ]
},

and while all objects are similarly treated, we finally get a tree.

If id === pid, the root node is found. This is the object for the later return.

var data = [
        { "id": "f", "pid": "b", "name": "F" },
        { "id": "e", "pid": "c", "name": "E" },
        { "id": "d", "pid": "c", "name": "D" },
        { "id": "c", "pid": "b", "name": "C" },
        { "id": "a", "pid": "a", "name": "A" },
        { "id": "b", "pid": "a", "name": "B" }
    ],
    tree = function (data) {
        var r, o = Object.create(null);
        data.forEach(function (a) {
            a.children = o[a.id] && o[a.id].children;
            o[a.id] = a;
            if (a.id === a.pid) {
                r = a;
            } else {
                o[a.pid] = o[a.pid] || {};
                o[a.pid].children = o[a.pid].children || [];
                o[a.pid].children.push(a);
            }
        });
        return r;
    }(data);

console.log(tree);

Influenced by the answer of Nina, this is my resolution just for the record.

function corrugate(data){
  var root = "";
  return data.reduce((t,o) => {
    	                       o.id === o.pid && (root = o.id);
  	                           t[o.id]  ? t[o.id].name = o.name
  	                                    : t[o.id] = {id: o.id, name: o.name};
  	                           t[o.pid] ? o.pid !== o.id ? t[o.pid].children.push(t[o.id])
  	                                                     : t[o.pid].children = t[o.pid].children || []
  	                                    : t[o.pid] = {id: o.pid, children: [t[o.id]]};
  	                           return t;
                              },{})[root];
}

var   data = [{ "id": "f", "pid": "b", "name": "F" },
              { "id": "e", "pid": "c", "name": "E" },
              { "id": "b", "pid": "a", "name": "B" },
              { "id": "d", "pid": "c", "name": "D" },
              { "id": "c", "pid": "b", "name": "C" },
              { "id": "a", "pid": "a", "name": "A" }
             ];
console.log(corrugate(data));

Post a comment

comment list (0)

  1. No comments so far