Hierarchical Json from Flat With Parent Id

Hierarchical json from flat with parent ID

Try something like

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)

Demo: Fiddle

Result

[{
"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" : []
}]
}]
}]

Create Json Hierarchy from from raw data of parent child id

Assuming the data table looks like this:

Map<Integer, Integer> childToParent = new HashMap<>();
childToParent.put(1, 1);
childToParent.put(2, 1);
childToParent.put(3, 1);
childToParent.put(4, 2);
childToParent.put(5, 2);

We can create a parent to children map:

Map<Integer, List<Integer>> parentToChildren = childToParent.entrySet().stream()
.collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.mapping(Map.Entry::getKey, Collectors.toList())));

For simplicity, let's create a Company class likewise:

@Data
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Company {
private final int id;
@JsonProperty(value = "child")
private List<Company> children;
}

Then create Company objects:

Map<Integer, Company> idToCompany = childToParent.keySet().stream()
.map(integer -> new Company(integer, null))
.collect(Collectors.toMap(Company::getId, company -> company));

And now we can set the children for each parent:

idToCompany.values().forEach(company -> {
List<Integer> childrenIds = parentToChildren.get(company.getId());

if(childrenIds != null){
List<Company> children = childrenIds.stream()
.filter(childId -> childId != company.getId()) // a company can't be a parent of itself
.map(idToCompany::get)
.collect(Collectors.toList());
company.setChildren(children);
}
});

Now we can extract the "head" companies like this:

List<Company> companiesHeads = childToParent.entrySet().stream()
.filter(childIdToParentId -> childIdToParentId.getKey().equals(childIdToParentId.getValue()))
.map(Map.Entry::getKey)
.map(idToCompany::get)
.collect(Collectors.toList());

And print to the screen in JSON format:

ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
System.out.println(mapper.writeValueAsString(companiesHeads));

Output:

[ {
"id" : 1,
"child" : [ {
"id" : 2,
"child" : [ {
"id" : 4
}, {
"id" : 5
} ]
}, {
"id" : 3
} ]
} ]

Hierarchical json to flat with parent ID

You can use recursive function to return one array of objects

var arr =[{"s_gid":0,"title":"scholastic Master List 2016","nodes":[{"Id":"1","templateId":"1","s_gid":"10","m_s_p_id":"1","subject_group_name":"xxxxxxx","parent_id":"1","sname":"","nodes":[{"Id":"2","templateId":"1","s_gid":"100","m_s_p_id":"0","subject_group_name":"abc","parent_id":"10","sname":"","nodes":[{"Id":"3","templateId":"1","s_gid":"1000","m_s_p_id":"0","subject_group_name":"efg","parent_id":"100","sname":""}]}]}]}]
function flatten(data) { var result = []; data.forEach(function(o) { var obj = {} for(var e in o) { (Array.isArray(o[e])) ? result.push(...flatten(o[e])) : obj[e] = o[e]; } result.push(obj) }) return result;}
console.log(flatten(arr))

Convert nested Json to flat Json with parentId to every node

You could take an iterative and recursive approach by using a function which takes an array and a parent id for the actual level.

If a property starts with child, it calls the function again with the actual _id and pushes all items to the result set.

function getFlat(array, parentid) {    return array.reduce((r, o) => {        var temp = {};        r.push(temp);        Object.entries(o).forEach(([k, v]) => {            if (k.startsWith('child')) {                r.push(...getFlat(v, o._id));            } else {                temp[k] = v;            }        });        temp.parentid = parentid;        return r;    }, []);}

var data = [{ child1: [{ _type: "EntityChild1", name: "Test222", _id: 2 }], child2: [{ _type: "EntityChild2", name: "Test333", _id: 3, child2_child1: [{ _type: "EntityChild2_1", name: "Test444", _id: 6, child2_child1_child1: [{ _type: "EntityChild2_1_1", name: "Test555", _id: 7 }] }] }], _type: "EntityParent", name: "Test000", _id: 1, child3: [{ _type: "EntityChild3", name: "Test111", _id: 4 }], child4: [{ _type: "EntityChild4", name: "Test666", _id: 5 }] }], flat = getFlat(data, -1);
console.log(flat);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Flat JSON unflatten to hierarchy with multiple parents as String

You could use this solution:

var data = [  { "title": "any", "parentids": [] },  { "title": "culture", "parentids": ["any"] },  { "title": "building", "parentids": ["any"] },  { "title": "museum", "parentids": ["culture", "building"] },]
// For each object in data, assign a children property.data.forEach(o => o.children = [])
// For each object in data, assign a key/object pair using the title e.g// { // culture: { "title": "culture", "parentids": ["any"] }} // ... // }const map = data.reduce((a, o) => (a[o.title] = o, a), {})
// For each object in data, and for each parentid in that object,// push this object to the object where the given parentid === IDdata.forEach(o => o.parentids.forEach(id => map[id] && map[id].children.push(o)))
// Filter the data object to only root elements (where there are no parentids)const output = data.filter(e => !e.parentids.length)
console.log(output);

Hierarchical json to flat with parent ID

You can use recursive function to return one array of objects

var arr =[{"s_gid":0,"title":"scholastic Master List 2016","nodes":[{"Id":"1","templateId":"1","s_gid":"10","m_s_p_id":"1","subject_group_name":"xxxxxxx","parent_id":"1","sname":"","nodes":[{"Id":"2","templateId":"1","s_gid":"100","m_s_p_id":"0","subject_group_name":"abc","parent_id":"10","sname":"","nodes":[{"Id":"3","templateId":"1","s_gid":"1000","m_s_p_id":"0","subject_group_name":"efg","parent_id":"100","sname":""}]}]}]}]
function flatten(data) { var result = []; data.forEach(function(o) { var obj = {} for(var e in o) { (Array.isArray(o[e])) ? result.push(...flatten(o[e])) : obj[e] = o[e]; } result.push(obj) }) return result;}
console.log(flatten(arr))

Convert flat data to hierarchical with inner objects javascript

The code below is full source code for your situation. I modified and added a few lines from your source code.
Note that this code assumes that parents are always inserted to this tree before their children do. If this assumption is not always true then your code need to be changed more than this.

let flatData = [
{
"id": 1,
"name": "Sponsor",
"description": null,
"parentId": null
},
{
"id": 2,
"name": "Class",
"description": null,
"parentId": 1
},
{
"id": 3,
"name": "Study",
"description": null,
"parentId": 2
},
{
"id": 4,
"name": "Site",
"description": null,
"parentId": 3
}
];

function convertItem(item) {
let newItem = {};
newItem.data = item;
return newItem;
}

function flatToHierarchy(flat) {

let roots = [];
let all = {};
let ids = [];

flat.forEach(function (item) {
let itemId = item.id;
let convertedItem = convertItem(item);
all[itemId] = convertedItem;
ids.push(itemId);
});

// We use ids array instead of object to maintain its previous order.
for (let i = 0; i < ids.length; i++) {
let id = ids[i];
let convertedItem = all[id];
let parentId = convertedItem.data.parentId;

if (parentId === null) {
delete convertedItem.data.parentId;
delete convertedItem.data.id;
roots.push(convertedItem);
} else if (parentId in all) {
let p = all[parentId];
if (!('Children' in p)) {
p.children = []
}
delete convertedItem.data.parentId;
delete convertedItem.data.id;
p.children.push(convertedItem)
}
};

console.log(roots);
return roots
}

flatToHierarchy(flatData);

We can factor out two deletes before push.



Related Topics



Leave a reply



Submit