私はこのスクリプトを別の投稿から盗みました:
function convertToHierarchy() {
var arry = [{ "Id": "1", "Name": "abc", "Parent": "", "attr": "abc" },
{ "Id": "2", "Name": "abc", "Parent": "1", "attr": "abc" },
{ "Id": "3", "Name": "abc", "Parent": "2", "attr": "abc" },
{ "Id": "4", "Name": "abc", "Parent": "2", "attr": "abc" }];
var nodeObjects = createStructure(arry);
for (var i = nodeObjects.length - 1; i >= 0; i--) {
var currentNode = nodeObjects[i];
if (currentNode.value.Parent === "") {
continue;
}
var parent = getParent(currentNode, nodeObjects);
if (parent === null) {
continue;
}
parent.children.Push(currentNode);
nodeObjects.splice(i, 1);
}
console.dir(nodeObjects);
return nodeObjects;
}
function createStructure(nodes) {
var objects = [];
for (var i = 0; i < nodes.length; i++) {
objects.Push({ value: nodes[i], children: [] });
}
return objects;
}
function getParent(child, nodes) {
var parent = null;
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].value.Id === child.value.Parent) {
return nodes[i];
}
}
return parent;
}
このスクリプトは以下を生成します。
[{
"value": {
"Id": "1",
"Name": "abc",
"Parent": "",
"attr": "abc"
},
"children": [{
"value": {
"Id": "2",
"Name": "abc",
"Parent": "1",
"attr": "abc"
},
"children": [{
"value": {
"Id": "4",
"Name": "abc",
"Parent": "2",
"attr": "abc"
},
"children": []
}, {
"value": {
"Id": "3",
"Name": "abc",
"Parent": "2",
"attr": "abc"
},
"children": []
}]
}]
}]
私が探しているのは:
[{
"Id": "1",
"Name": "abc",
"Parent": "",
"attr": "abc",
"children": [{
"Id": "2",
"Name": "abc",
"Parent": "1",
"attr": "abc",
"children": [{
"Id": "4",
"Name": "abc",
"Parent": "2",
"attr": "abc"
}, {
"Id": "3",
"Name": "abc",
"Parent": "2",
"attr": "abc"
}]
}]
}]
主に「値」ラッパーを削除し、次に空の子ノードを削除する必要があります。クリーンアップスクリプトを作成できることはわかっていますが、それはベストプラクティスとは言えません。誰かが修正する方法を知っているか、別のスクリプトを提案するなら素晴らしいでしょう!
ありがとう
次のようなものを試してください
var arry = [{ "Id": "1", "Name": "abc", "Parent": "", "attr": "abc" },
{ "Id": "2", "Name": "abc", "Parent": "1", "attr": "abc" },
{ "Id": "3", "Name": "abc", "Parent": "2", "attr": "abc" },
{ "Id": "4", "Name": "abc", "Parent": "2", "attr": "abc" }];
function convert(array){
var map = {};
for(var i = 0; i < array.length; i++){
var obj = array[i];
obj.items= [];
map[obj.Id] = obj;
var parent = obj.Parent || '-';
if(!map[parent]){
map[parent] = {
items: []
};
}
map[parent].items.Push(obj);
}
return map['-'].items;
}
var r = convert(arry)
デモ: フィドル
結果
[{
"Id" : "1",
"Name" : "abc",
"Parent" : "",
"attr" : "abc",
"children" : [{
"Id" : "2",
"Name" : "abc",
"Parent" : "1",
"attr" : "abc",
"children" : [{
"Id" : "3",
"Name" : "abc",
"Parent" : "2",
"attr" : "abc",
"children" : []
}, {
"Id" : "4",
"Name" : "abc",
"Parent" : "2",
"attr" : "abc",
"children" : []
}]
}]
}]
@Arun P Johnyの答えは良いですが、問題があります。配列がソートされていない場合、サブツリーがフラッシュされます。このように更新しました。
var arry = [
{ "Id": "5", "Name": "abc", "Parent": "3", "attr": "abc" },
{ "Id": "2", "Name": "abc", "Parent": "1", "attr": "abc" },
{ "Id": "4", "Name": "abc", "Parent": "2", "attr": "abc" },
{ "Id": "3", "Name": "abc", "Parent": "2", "attr": "abc" },
{ "Id": "1", "Name": "abc", "Parent": "", "attr": "abc" }
];
function convert(array){
var map = {}
for(var i = 0; i < array.length; i++){
var obj = array[i]
if(!(obj.Id in map)){
map[obj.Id] = obj
map[obj.Id].children = []
}
if(typeof map[obj.Id].Name == 'undefined'){
map[obj.Id].Id = obj.Id
map[obj.Id].Name = obj.Name
map[obj.Id].attr = obj.attr
map[obj.Id].Parent= obj.Parent
}
var parent = obj.Parent || '-';
if(!(parent in map)){
map[parent] = {}
map[parent].children = []
}
map[parent].children.Push(map[obj.Id])
}
return map['-']
}
console.log(JSON.stringify(convert(arry)))
結果は次のとおりです。
{
"children": [
{
"children": [
{
"Id": "2",
"Name": "abc",
"Parent": "1",
"attr": "abc",
"children": [
{
"Id": "4",
"Name": "abc",
"Parent": "2",
"attr": "abc",
"children": []
},
{
"children": [
{
"Id": "5",
"Name": "abc",
"Parent": "3",
"attr": "abc",
"children": []
}
],
"Id": "3",
"Name": "abc",
"attr": "abc",
"Parent": "2"
}
]
}
],
"Id": "1",
"Name": "abc",
"attr": "abc",
"Parent": ""
}
]
}
function convert(rows) {
function exists(rows, Parent) {
for (var i = 0; i < rows.length; i++) {
if (rows[i].Id == Parent) return true;
}
return false;
}
var nodes = [];
// get the top level nodes
for (var i = 0; i < rows.length; i++) {
var row = rows[i];
if (!exists(rows, row.Parent)) {
nodes.Push({
id: row.Id,
name: row.Name,
attr: row.attr
});
}
}
var toDo = [];
for (var i = 0; i < nodes.length; i++) {
toDo.Push(nodes[i]);
}
while (toDo.length) {
var node = toDo.shift();
// the parent node
// get the children nodes
for (var i = 0; i < rows.length; i++) {
var row = rows[i];
if (row.Parent == node.Id) {
var child = {
Id: row.Id,
Name: row.Name,
attr: row.attr
};
if (node.options) {
node.options.Push(child);
} else {
node.options = [child];
}
toDo.Push(child);
}
}
}
return nodes;}
パラメータを受け入れる改良版。
function convert(rows, options) {
var options = options || {};
var idProp = options.id || 'id';
var parentProp = options.parent || 'parent';
var childProp = options.children || 'children';
function exists(rows, parent) {
for (var i = 0; i < rows.length; i++) {
if (rows[i][idProp] == parent) return true;
}
return false;
}
var nodes = [];
// get the top level nodes
for (var i = 0; i < rows.length; i++) {
var row = rows[i];
if (!exists(rows, row[parentProp])) {
nodes.Push(Object.assign({}, row));
}
}
var toDo = [];
for (var i = 0; i < nodes.length; i++) {
toDo.Push(nodes[i]);
}
while (toDo.length) {
var node = toDo.shift();
// the parent node
// get the children nodes
for (var i = 0; i < rows.length; i++) {
var row = rows[i];
if (row[parentProp] == node[idProp]) {
var child = Object.assign({}, row);
node[childProp] = node[childProp] || [];
node[childProp].Push(child);
toDo.Push(child);
}
}
}
return nodes;
}
// Usage
var data = [...];
convert(data);
// Or
convert(data, { id: 'Id', parent: 'Parent', children: 'Children' });
//このようにしてみてください.................。
function prepareFlatArrayListToTreeViewList(arry) {
var treeviewList= angular.copy(flatListToTreeViewData(arry));
return treeviewList;
}
// json形式のデータを返します
function flatListToTreeViewData(dataList) {
var tree = [],
mappedArr = {},
arrElem,
mappedElem;
// First map the nodes of the array to an object -> create a hash table.
for (var i = 0, len = dataList.length; i < len; i++) {
arrElem = dataList[i];
mappedArr[arrElem.id] = arrElem;
mappedArr[arrElem.id]['children'] = [];
}
for (var id in mappedArr) {
if (mappedArr.hasOwnProperty(id)) {
mappedElem = mappedArr[id];
// If the element is not at the root level, add it to its parent array of children.
if (mappedElem.parentID) {
mappedArr[mappedElem['parentID']]['children'].Push(mappedElem);
}
// If the element is at the root level, add it to first level elements array.
else {
tree.Push(mappedElem);
}
}
}
return tree;
}