Expand Json based on relation - javascript

I have following JSON data, If any one of the child name is matching with any of the parent name then i want to create new json set.
var PARENT_CHILD = {
'Newton': ['Plato', 'Aristotle'],
'Aristotle': ['Einstein'],
'Plato': ['Tesla', 'Edison'],
'Einstein': ['Hawking']
};
I want to convert it into like below:
{
"Newton": {
"child": "Plato, Aristotle"
},
"Plato": {
"parent": "Newton",
"child": "Tesla, Edison"
},
"Aristotle": {
"parent": "Newton",
"child": "Einstein"
},
"Einstein": {
"parent": "Aristotle",
"child": "Hawking"
},
"Tesla": {
"parent": "Plato"
},
"Edison": {
"parent": "Plato"
},
"Hawking": {
"parent": "Einstein"
}
}

You can use Array.reduce on the entries in PARENT_CHILD, creating a new entry in the output for the parent (if it doesn't already exist) and adding the child array to it, and then creating a new entry (with parent property) for each of the children of that parent:
var PARENT_CHILD = {
'Newton': ['Plato', 'Aristotle'],
'Aristotle': ['Einstein'],
'Plato': ['Tesla', 'Edison'],
'Einstein': ['Hawking']
};
var result = Object.entries(PARENT_CHILD).reduce((acc, [parent, child]) => {
if (acc[parent]) {
acc[parent].child = child.join(', ');
}
else {
acc[parent] = { child : child.join(', ') };
}
child.forEach(name => acc[name] = { parent });
return acc;
}, {});
console.log(result);

Related

How can I update this nested object's value if one of its properties match in JS?

I saw many answers, but I haven't been able to modify any to my need.
Object
{
"id": "476ky1",
"custom_id": null,
"name": "Reunião com o novo Gerente de Vendas - Airton",
"text_content": null,
"description": null,
"status": {
"id": "p3203621_11svBhbO"
},
"archived": false,
"creator": {
"id": 3184709
},
"time_spent": 0,
"custom_fields": [{
"id": "36c0de9a-9243-4259-ba57-bd590ba07fe0",
"name": "Comments",
"value": "dsdsdsds"
}],
"attachments": []
}
Within custom_fields, if the property name's value is Comments, update the value property.
I've tried it like this, using this approach, for example, but it doesn't produce the expected result.
const updatedComment = [{ name: "Comments", value: "The comment is updated"}];
updateNestedObj(taskData, updatedComment)
function updateNestedObj(obj, updates) {
const updateToApply = updates.find(upd => upd.id === obj.id);
if (updateToApply) {
obj.title = updateToApply.content;
obj.note = updateToApply.note;
}
// Apply updates to any child objects
for(let k in obj) {
if (typeof(obj[k]) === 'object') {
updateNestedObj(obj[k], updates);
}
}
}
You're using the wrong property names when you search updates for updateToApply, and then when assigning the value.
When you recurse on children, you need to distinguish between arrays and ordinary objects, so you can loop over the nested arrays. You also have to skip null properties, because typeof null == 'object'.
const updatedComment = [{
name: "Comments",
value: "The comment is updated"
}];
function updateNestedObj(obj, updates) {
let updateToApply = updates.find(upd => upd.name == obj.name);
if (updateToApply) {
obj.value = updateToApply.value;
}
// Apply updates to any child objects
Object.values(obj).forEach(child => {
if (Array.isArray(child)) {
child.forEach(el => updateNestedObj(el, updates));
} else if (typeof(child) === 'object' && child != null) {
updateNestedObj(child, updates);
}
});
}
const taskData = {
"id": "476ky1",
"custom_id": null,
"name": "Reunião com o novo Gerente de Vendas - Airton",
"text_content": null,
"description": null,
"status": {
"id": "p3203621_11svBhbO"
},
"archived": false,
"creator": {
"id": 3184709
},
"time_spent": 0,
"custom_fields": [{
"id": "36c0de9a-9243-4259-ba57-bd590ba07fe0",
"name": "Comments",
"value": "dsdsdsds"
}],
"attachments": []
};
updateNestedObj(taskData, updatedComment)
console.log(taskData);
Try this:
const updatedComment = [{ name: "Comments", value: "A new comment value" }]
// you can add as many updates as you want
function update(obj, updates) {
for (const update in updates) {
for (const field in obj.custom_fields) {
if (obj.obj.custom_fields.name == update.name) {
obj.obj.custom_fields.value = update.value
}
}
}
}
update(obj, updatedComment)

how to loop inside object array Angular

I want to display values from my json but I don't know how to do it. Is it possible to loop inside an object array ? i don't know if the keyvalue pipe can help me but I want to do without.
how to get the student2 and also the name to display it ?
thanks everyone.
json
{
"student": {
"student1": [],
"student2": [
{
"id": "123",
"name": "boot"
},
"student3": [],
]
},
"teacher": {
"teacher1": [],
"teacher2": [
{
"id": "123456",
"name": "toto"
},
]
}
}
ts.file
get(){
this.service.getAll().subscribe((data:any) => {
object.keys(data).length > 0;
})
}
Assuming your JSON object from your GET request looks like the one you posted above simply do:
get(){
this.service.getAll().subscribe((data:any) => {
data.student.forEach(element => {
for (let key in element) {
console.log(" key:", key, "value:", element[key]);
for (let val in element[key]) {
console.log(" value:", val);
}
}
});
})
}

Get values for a matching key recursively from object

I have this json object
{
"data": {
"user": {
"user_info": {
"id": "AoGC2HQ9vedHmzcMX"
},
"product": [
{
"node": {
"id": "NzcxNzU2ODU1ODM1",
"feedback": {
"raters": {
"nodes": [
{
"id": "1",
"name": "Dan"
},
{
"id": "2",
"name": "Allen"
},
{
"id": "3",
"name": "Williams"
}
]
},
"commentors": {
"nodes": [
{
"id": "001",
"name": "Kent"
},
{
"id": "002",
"name": "Jay"
}
]
}
}
}
}
]
}
}
}
So how do I make it to get values of id If the parent property matches the desired key name, In this example I want to get all id's from raters.nodes only.
so expected result is
[1,2,3]
I know can do obj.data.user.product[0].node.feedback.raters.nodes and loop through that, but that is not how I want and the object tree occasionally changes.
I have used this recursive function
const recursiveSearch = (obj, searchKey, results = []) => {
const r = results;
Object.keys(obj).forEach(key => {
const value = obj[key];
if(key === searchKey && typeof value !== 'object'){
r.push(value);
}else if(typeof value === 'object'){
recursiveSearch(value, searchKey, r);
}
});
return r;
};
//returns all id's
While it works, it returns all id values, so how do I improve it? If not, how do I make this possible?
I think you want to really do this in 2 steps,..
First make a function to get the root node your looking for, and then you can just use map like normal.
Below is an example.
var data = JSON.parse("{\"data\":{\"user\":{\"user_info\":{\"id\":\"AoGC2HQ9vedHmzcMX\"},\"product\":[{\"node\":{\"id\":\"NzcxNzU2ODU1ODM1\",\"feedback\":{\"raters\":{\"nodes\":[{\"id\":\"1\",\"name\":\"Dan\"},{\"id\":\"2\",\"name\":\"Allen\"},{\"id\":\"3\",\"name\":\"Williams\"}]},\"commentors\":{\"nodes\":[{\"id\":\"001\",\"name\":\"Kent\"},{\"id\":\"002\",\"name\":\"Jay\"}]}}}}]}}}");
function getRoot(data, search) {
function get(path, data) {
for (const [k, v] of Object.entries(data)) {
if (v instanceof Object) {
const pp = `${path}.${k}`;
if (pp.slice(-search.length) === search) {
return v;
}
const r = get(`${path}.${k}`, v);
if (r) return r;
}
}
}
return get('', data);
}
const r = getRoot(data, 'raters.nodes');
console.log(r && r.map(i => i.id));

Modify javascript object to specific format

let data = {
"rec": [{
"id": "25837",
"contentId": "25838"
},
{
"id": "25839",
"contentId": "25838"
},
{
"id": "25838"
},
{
"id": "25636",
"contentId": "25837"
}, {
"id": "25640",
"contentId": "25839"
}
]
};
I have a javascript object which I have to manipulate to below format.
{
"childern": [{
"id": "25838",
"childern": [{
"id": "25837",
"contentId": "25838",
"childern": [{
"id": "25636",
"contentId": "25837"
}]
},
{
"id": "25839",
"contentId": "25838",
"childern": [{
"id": "25640",
"contentId": "25839"
}]
}
]
}]
}
If any object dont have contentId it should be at parent level. then all the objects having contentId same as parent id should be at its child level and so on.
I have created a fiddle here but logic is not completed. Any idea or reference to achieve this.
You could create recursive function with reduce method to get the desired result.
let data = {"rec":[{"id":"25837","contentId":"25838"},{"id":"25839","contentId":"25838"},{"id":"25838"},{"id":"25636","contentId":"25837"},{"id":"25640","contentId":"25839"}]}
function nest(data, pid) {
return data.reduce((r, e) => {
if (pid == e.contentId) {
const obj = { ...e }
const children = nest(data, e.id);
if (children.length) obj.children = children
r.push(obj)
}
return r;
}, [])
}
const result = nest(data.rec);
console.log(result[0])

Reverse Traverse a hierarchy

I have a hierarchy of objects that contain the parent ID on them. I am adding the parentId to the child object as I parse the json object like this.
public static fromJson(json: any): Ancestry | Ancestry[] {
if (Array.isArray(json)) {
return json.map(Ancestry.fromJson) as Ancestry[];
}
const result = new Ancestry();
const { parents } = json;
parents.forEach(parent => {
parent.parentId = json.id;
});
json.parents = Parent.fromJson(parents);
Object.assign(result, json);
return result;
}
Any thoughts on how to pull out the ancestors if I have a grandchild.id?
The data is on mockaroo curl (Ancestries.json)
As an example, with the following json and a grandchild.id = 5, I would create and array with the follow IDs
['5', '0723', '133', '1']
[{
"id": "1",
"name": "Deer, spotted",
"parents": [
{
"id": "133",
"name": "Jaime Coldrick",
"children": [
{
"id": "0723",
"name": "Ardys Kurten",
"grandchildren": [
{
"id": "384",
"name": "Madelle Bauman"
},
{
"id": "0576",
"name": "Pincas Maas"
},
{
"id": "5",
"name": "Corrie Beacock"
}
]
},
There is perhaps very many ways to solve this, but in my opinion the easiest way is to simply do a search in the data structure and store the IDs in inverse order of when you find them. This way the output is what you are after.
You could also just reverse the ordering of a different approach.
I would like to note that the json-structure is a bit weird. I would have expected it to simply have nested children arrays, and not have them renamed parent, children, and grandchildren.
let data = [{
"id": "1",
"name": "Deer, spotted",
"parents": [
{
"id": "133",
"name": "Jaime Coldrick",
"children": [
{
"id": "0723",
"name": "Ardys Kurten",
"grandchildren": [
{
"id": "384",
"name": "Madelle Bauman"
},
{
"id": "0576",
"name": "Pincas Maas"
},
{
"id": "5",
"name": "Corrie Beacock"
}
]
}]
}]
}]
const expectedResults = ['5', '0723', '133', '1']
function traverseInverseResults(inputId, childArray) {
if(!childArray){ return }
for (const parent of childArray) {
if(parent.id === inputId){
return [parent.id]
} else {
let res = traverseInverseResults(inputId, parent.parents || parent.children || parent.grandchildren) // This part is a bit hacky, simply to accommodate the strange JSON structure.
if(res) {
res.push(parent.id)
return res
}
}
}
return
}
let result = traverseInverseResults('5', data)
console.log('results', result)
console.log('Got expected results?', expectedResults.length === result.length && expectedResults.every(function(value, index) { return value === result[index]}))

Categories

Resources