let obj = {
"options": [
{
"id": "a",
"name": "a",
"options": [
{
"id": "a.1",
"options": [
{
"id": "a.1.1",
"name": "a.1.1"
},
{
"id": "a.1.2",
"name": "a.1.2"
},
{
"id": "a.1.3",
"name": "a.1.3"
}
]
},
{
"id": "a.2",
"name": "a.2",
"options": [
{
"id": "a.2.1",
"name": "a.2.1"
},
{
"id": "a.2.2",
"name": "a.2.2"
},
{
"id": "a.2.3",
"name": "a.2.3"
}
]
},
{
"id": "a.3",
"name": "a.3",
"options": [
{
"id": "a.3.1",
"name": "a.3.1"
},
{
"id": "a.3.2",
"name": "a.3.1"
},
{
"id": "a.3.3",
"name": "a.3.1"
}
]
}
]
},
{
"name": "b",
"id": "b",
"options": [
{
"id": "b.1",
"name": "b.1",
"options": [
{
"id": "b.1.1",
"name": "b.1.1"
},
{
"id": "b.1.2",
"name": "b.1.2"
},
{
"id": "b.1.3",
"name": "b.1.3"
}
]
},
{
"id": "b.2",
"name": "b.2",
"options": [
{
"id": "b.2.1",
"name": "b.2.1"
},
{
"id": "b.2.2",
"name": "b.2.2"
},
{
"id": "b.2.3",
"name": "b.2.3"
}
]
},
{
"id": "b.3",
"name": "b.3.1",
"options": [
{
"id": "b.3.1",
"name": "b.3.1"
},
{
"id": "b.3.2",
"name": "b.3.2"
},
{
"id": "b.3.3",
"name": "b.3.3"
}
]
}
]
},
{
"id": "c",
"name": "c",
"options": [
{
"id": "c.1",
"name": "c.1",
"options": [
{
"id": "c.1.1",
"name": "c.1.1"
},
{
"id": "c.1.2",
"name": "c.1.2"
},
{
"id": "c.1.3",
"name": "c.1.3"
}
]
},
{
"id": "c.2",
"name": "c.2",
"options": [
{
"id": "c.2.1",
"name": "c.2.1"
},
{
"id": "c.2.2",
"name": "c.2.2"
},
{
"id": "c.2.3",
"name": "c.2.3"
}
]
},
{
"id": "c.3",
"name": "c.3",
"options": [
{
"id": "c.3.1",
"name": "c.3.1"
},
{
"id": "c.3.2",
"name": "c.3.2"
},
{
"id": "c.3.3",
"name": "c.3.3"
}
]
}
]
}
]
}
" I have this object
I neeed to create a function getHierarchy, that an option ID as its input, finds the option in the
list and returns the ID of all it's parents.
for example,getHierarchy("a.1.3") should return the following result ["a","a.1","a.1.3"]
getHierarchy("c.3.3") should return the following result ["c","c.3","c.3.3"] "
assuming id is unique;
function getHierarchy(object, id, prev) {
if (!object.options) return;
for (const child of object.options) {
if(child.id === id) {
return [...prev, object.id, child.id];
}
result = getHierarchy(child, id, [...prev, object.id]);
if (result) return result;
}
}
getHierarchy(obj, "a.1.3", []);
Here an recursive solution i hope this helps you.
let obj = {
"options": [
{
"id": "a",
"name": "a",
"options": [
{
"id": "a.1",
"options": [
{
"id": "a.1.1",
"name": "a.1.1"
},
{
"id": "a.1.2",
"name": "a.1.2"
},
{
"id": "a.1.3",
"name": "a.1.3"
}
]
},
{
"id": "a.2",
"name": "a.2",
"options": [
{
"id": "a.2.1",
"name": "a.2.1"
},
{
"id": "a.2.2",
"name": "a.2.2"
},
{
"id": "a.2.3",
"name": "a.2.3"
}
]
},
{
"id": "a.3",
"name": "a.3",
"options": [
{
"id": "a.3.1",
"name": "a.3.1"
},
{
"id": "a.3.2",
"name": "a.3.1"
},
{
"id": "a.3.3",
"name": "a.3.1"
}
]
}
]
},
{
"name": "b",
"id": "b",
"options": [
{
"id": "b.1",
"name": "b.1",
"options": [
{
"id": "b.1.1",
"name": "b.1.1"
},
{
"id": "b.1.2",
"name": "b.1.2"
},
{
"id": "b.1.3",
"name": "b.1.3"
}
]
},
{
"id": "b.2",
"name": "b.2",
"options": [
{
"id": "b.2.1",
"name": "b.2.1"
},
{
"id": "b.2.2",
"name": "b.2.2"
},
{
"id": "b.2.3",
"name": "b.2.3"
}
]
},
{
"id": "b.3",
"name": "b.3.1",
"options": [
{
"id": "b.3.1",
"name": "b.3.1"
},
{
"id": "b.3.2",
"name": "b.3.2"
},
{
"id": "b.3.3",
"name": "b.3.3"
}
]
}
]
},
{
"id": "c",
"name": "c",
"options": [
{
"id": "c.1",
"name": "c.1",
"options": [
{
"id": "c.1.1",
"name": "c.1.1"
},
{
"id": "c.1.2",
"name": "c.1.2"
},
{
"id": "c.1.3",
"name": "c.1.3"
}
]
},
{
"id": "c.2",
"name": "c.2",
"options": [
{
"id": "c.2.1",
"name": "c.2.1"
},
{
"id": "c.2.2",
"name": "c.2.2"
},
{
"id": "c.2.3",
"name": "c.2.3"
}
]
},
{
"id": "c.3",
"name": "c.3",
"options": [
{
"id": "c.3.1",
"name": "c.3.1"
},
{
"id": "c.3.2",
"name": "c.3.2"
},
{
"id": "c.3.3",
"name": "c.3.3"
}
]
}
]
}
]
}
function getHierarchy(opts, path, index = 1, result = []) {
if(!opts) return result;
let objPaths = path.split(".");
let _path = objPaths.slice(0, index).join(".");
let option = opts.find(({id}) => id === _path);
if(!option) return result;
let { options, id } = option;
return getHierarchy(options, path, ++index, [...result,id]);
}
let result = getHierarchy(obj.options, "a.1.3");
console.log(result);
Related
BE Response:- which I am getting from Backend Service
{
"data": {
"type": "AnyType",
"resources": [
{
"id": 1,
"treeId": "1",
"name": "name1",
"description": "description1",
"children": [
{
"id": 3,
"treeId": "1-3",
"name": "subName1",
"description": "subDescription1",
"children": [
{
"id": 6,
"treeId": "1-3-6",
"name": "subSubName1",
"description": "subSubDesc1",
"children": []
}
]
}
]
},
{
"id": 2,
"treeId": "2",
"name": "name2",
"description": "description2",
"children": [
{
"id": 7,
"treeId": "2-7",
"name": "subName2",
"description": "subDescription2",
"children": []
}
]
}
]
}
}
But I need to modify this response to as below on FE
Expected Response:- means I need to join name and description field text to one(in name field ) as below:-
{
"data": {
"type": "AnyType",
"resources": [
{
"id": 1,
"treeId": "1",
"name": "name1-description1",
"description": "description1",
"children": [
{
"id": 3,
"treeId": "1-3",
"name": "subName1-subDescription1",
"description": "subDescription1",
"children": [
{
"id": 6,
"treeId": "1-3-6",
"name": "subSubName1-subSubDesc1",
"description": "subSubDesc1",
"children": []
}
]
}
]
},
{
"id": 2,
"treeId": "2",
"name": "name2-description2",
"description": "description2",
"children": [
{
"id": 7,
"treeId": "2-7",
"name": "subName2-subDescription2",
"description": "subDescription2",
"children": []
}
]
}
]
}
}
there could be n number of children of each object and children can have an array of objects.
What I have done:- I am able to change the very first name but not children name
let resDataArry = [];
let descData: DynamicResource;
response.forEach((x, index) => {
const descName = x.name + ' ' + x.description;
descData = { ...tree.resources[index], name: descName };
resDataArry.push(descData);
});
return resDataArry;
Please help.
You can use nested Array#forEach to access children array and then concatenate the name and description together.
let data = {
"data": {
"type": "AnyType",
"resources": [
{
"id": 1,
"treeId": "1",
"name": "name1",
"description": "description1",
"children": [
{
"id": 3,
"treeId": "1-3",
"name": "subName1",
"description": "subDescription1",
"children": [
{
"id": 6,
"treeId": "1-3-6",
"name": "subSubName1",
"description": "subSubDesc1",
"children": []
}
]
}
]
},
{
"id": 2,
"treeId": "2",
"name": "name2",
"description": "description2",
"children": [
{
"id": 7,
"treeId": "2-7",
"name": "subName2",
"description": "subDescription2",
"children": []
}
]
}
]
}
}
data.data.resources.forEach(function(item){
item.name = item.name + ' ' + item.description;
item.children.forEach(function(child){
child.name = child.name + ' ' + child.description;
});
});
console.log(data);
I have an array of data like this one
[
{
"id": "root_01",
"parents": [
{
"id": "parent_1",
"childrens": [
{
"id": "child_01",
"name": "ABC",
"group": "group_a"
},
{
"id": "child_02",
"name": "BBC",
"group": "group_b"
}
]
},
{
"id": "parent_2",
"childrens": [
{
"id": "child_03",
"name": "CCD",
"group": "group_a"
},
{
"id": "child_04",
"name": "EEF",
"group": "group_c"
}
]
}
]
},
{} // same as previous
]
and I'm trying to get rid of all parents data & catch & merge only child items like this one:
[
{
"id": "child_01",
"name": "ABC",
"group": "group_a"
},
{
"id": "child_02",
"name": "BBC",
"group": "group_b"
},
{
"id": "child_03",
"name": "CCD",
"group": "group_a"
},
{
"id": "child_04",
"name": "EEF",
"group": "group_c"
}
]
but after reading normalizr documentation I'm a little bit confused because I couldn't find this kind of example, so can anyone suggest me is it possible to make with normalizr or any better idea?
Thanks
Recusrion is what you need here:
const arr = [ { "id": "root_01", "parents": [ { "id": "parent_1", "childrens": [ { "id": "child_01", "name": "ABC", "group": "group_a" }, { "id": "child_02", "name": "BBC", "group": "group_b" } ] }, { "id": "parent_2", "childrens": [ { "id": "child_03", "name": "CCD", "group": "group_a" }, { "id": "child_04", "name": "EEF", "group": "group_c" } ] } ] }];
const flatten = arr => arr.flatMap(o=>o.parents ? flatten(o.parents) : o.childrens ? flatten(o.childrens) : o);
console.log(flatten(arr));
In vanilla JavaScript, how would I find unique locations from this object and make them keys, and place all items with that location as values. (can install lodash if necessary).
So this:
[
{
"item": {
"id": "cat"
},
"location": {
"id": "porch"
}
},
{
"item": {
"id": "dog"
},
"location": {
"id": "porch"
}
},
{
"item": {
"id": "snake"
},
"location": {
"id": "forest"
}
},
{
"item": {
"id": "bird"
},
"location": {
"id": "forest"
}
},
{
"item": {
"id": "beer"
},
"location": {
"id": "fridge"
}
}
]
Becomes this:
[
{
"porch": [
{
"id": "cat"
},
{
"id": "dog"
}
]
},
{
"forest": [
{
"id": "snake"
},
{
"id": "bird"
}
]
},
{
"fridge": [
{
"id": "beer"
}
]
}
]
PEN
// modified desired result
[
{
"location": {
"name": "porch",
"items": [
{
"title": "cat"
},
{
"title": "dog"
}
]
}
},
{
"location": {
"name": "forest",
"items": [
{
"title": "snake"
},
{
"title": "bird"
}
]
}
},
{
"location": {
"name": "fridge",
"items": [
{
"title": "beer"
}
]
}
}
]
let obj = [
{
"item": {
"id": "cat"
},
"location": {
"id": "porch"
}
},
{
"item": {
"id": "dog"
},
"location": {
"id": "porch"
}
},
{
"item": {
"id": "snake"
},
"location": {
"id": "forest"
}
},
{
"item": {
"id": "bird"
},
"location": {
"id": "forest"
}
},
{
"item": {
"id": "beer"
},
"location": {
"id": "fridge"
}
}
]
let result = {};
obj.forEach(({item, location}) => {
if(!result[location.id]) result[location.id] = []
result[location.id].push({title: item.id})
})
result = Object.keys(result).map(key => ({
"location": {
"name": key,
"items": result[key]
}
}))
result contains required output.
I have a raw data like this:
var data = {
"issues": [
{
"fields": {
"project": {
"key": "ProjectA"
},
"components": [
{
"name": "Component A"
},
{
"name": "Component C"
}
],
"priority": {
"name": "P0"
},
"status": {
"name": "Closed"
}
}
},
{
"fields": {
"project": {
"key": "ProjectA"
},
"components": [
{
"name": "Component B"
}
],
"priority": {
"name": "P1"
},
"status": {
"name": "Reopened"
}
}
},
{
"fields": {
"project": {
"key": "ProjectA"
},
"components": [
{
"name": "Component B"
}
],
"priority": {
"name": "P1"
},
"status": {
"name": "Closed"
}
}
},
{
"fields": {
"project": {
"key": "Project B"
},
"components": [
{
"name": "Component X"
}
],
"priority": {
"name": "P1"
},
"status": {
"name": "Closed"
}
}
}
]
};
If I give ProjectA as input, I would like to filter, group and aggregate the output as follows:
"components": [
{
"name": "Component A",
"priorities": [
{
"name": "P0",
"status": [
{
"name": "Open",
"count": 0
},
{
"name": "Reopened",
"count": 0
},
{
"name": "Closed",
"count": 1
}
]
},
{
"name": "P1",
"status": [
{
"name": "Open",
"count": 0
},
{
"name": "Reopened",
"count": 0
},
{
"name": "Closed",
"count": 0
}
]
}
]
},
{
"name": "Component B",
"priorities": [
{
"name": "P0",
"status": [
{
"name": "Open",
"count": 0
},
{
"name": "Reopened",
"count": 0
},
{
"name": "Closed",
"count": 0
}
]
},
{
"name": "P1",
"status": [
{
"name": "Open",
"count": 0
},
{
"name": "Reopened",
"count": 1
},
{
"name": "Closed",
"count": 1
}
]
}
]
},
{
"name": "Component C",
"priorities": [
{
"name": "P0",
"status": [
{
"name": "Open",
"count": 0
},
{
"name": "Reopened",
"count": 0
},
{
"name": "Closed",
"count": 1
}
]
},
{
"name": "P1",
"status": [
{
"name": "Open",
"count": 0
},
{
"name": "Reopened",
"count": 0
},
{
"name": "Closed",
"count": 0
}
]
}
]
}
]
I tried chaining, filtering, grouping, but not sure how to use this, since my data is too nested.
This is a proposal in plain javascript with first collecting all components and priorities and build then a result object and later increment the count of the status.
var data = { "issues": [{ "fields": { "project": { "key": "ProjectA" }, "components": [{ "name": "Component A" }, { "name": "Component C" }], "priority": { "name": "P0" }, "status": { "name": "Closed" } } }, { "fields": { "project": { "key": "ProjectA" }, "components": [{ "name": "Component B" }], "priority": { "name": "P1" }, "status": { "name": "Reopened" } } }, { "fields": { "project": { "key": "ProjectA" }, "components": [{ "name": "Component B" }], "priority": { "name": "P1" }, "status": { "name": "Closed" } } }, { "fields": { "project": { "key": "Project B" }, "components": [{ "name": "Component X" }], "priority": { "name": "P1" }, "status": { "name": "Closed" } } }] },
componentsO = Object.create(null),
prioritiesO = Object.create(null),
components,
priorities,
status_ = ['Open', 'Reopened', 'Closed'], // status collides in chrome with window.status
hash = Object.create(null),
getKey = function (a) { return a.join('|'); },
result = {};
data.issues.forEach(function (issue) {
if (issue.fields.project.key === 'ProjectA') {
issue.fields.components.forEach(function (component) {
componentsO[component.name] = true;
});
prioritiesO[issue.fields.priority.name] = true;
}
});
components = Object.keys(componentsO).sort();
priorities = Object.keys(prioritiesO).sort();
result.components = components.map(function (component) {
return {
name: component,
priorities: priorities.map(function (priority) {
return {
name: priority,
status: status_.map(function (status) {
var key = getKey([component, priority, status]);
hash[key] = { name: status, count: 0 };
return hash[key];
})
};
})
}
});
data.issues.forEach(function (issue) {
if (issue.fields.project.key === 'ProjectA') {
issue.fields.components.forEach(function (component) {
var key = getKey([component.name, issue.fields.priority.name, issue.fields.status.name]);
hash[key].count++;
});
}
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
This is the JSON Object i am working on :
var r={
"id": "A",
"name": "Analysis",
"url": "A.html",
"root": true,
"children": [
{
"id": "B",
"name": "Introduction",
"url": "B.html",
"root": true,
"children": [{
"id": "C",
"name": "Creating",
"url": "c.html#I1"
}, {
"id": "D",
"name": "Running",
"url": "d.html#I2"
}]
},
{
"id": "E",
"name": "Transient Analysis",
"url": "E.html",
"root": true,
"children": [{
"id": "F",
"name": "RC",
"url": "F.html#T1"
}, {
"id": "G",
"name": "RLC",
"url": "G.html#T2"
}]
}
]
}
I want this as another key-value
path="home.html"
and it should be appended not only to the root node but to all its children node.
So it should look like.
var r= {
"id": "A",
"name": "Analysis",
"url": "A.html",
"path":"home.html",
"root": true,
"children": [
{
"id": "B",
"name": "Introduction",
"url": "B.html",
"root": true,
"path":"home.html",
"children": [{
"id": "C",
"name": "Creating",
"url": "c.html#I1",
"path":"home.html"
}, {
"id": "D",
"name": "Running",
"url": "d.html#I2",
"path":"home.html"
}]
},
{
"id": "E",
"name": "Transient Analysis",
"url": "E.html",
"root": true,
"path":"home.html",
"children": [{
"id": "F",
"name": "RC",
"url": "F.html#T1",
"path":"home.html"
}, {
"id": "G",
"name": "RLC",
"url": "G.html#T2",
"path":"home.html"
} ]
}
]
}
so far I've tried is this :
r.path={"home.html"}
and
var to_concatjson = JSON.parse(r);
to_concatjson["path"] = {"home.html"};
but both are not working for me.
Further Modifications in the above question :
Lets say i am loading my json content from my File 1
File 1 looks like
[
{
"id":"a", "name":"a","children":[
{ "id":"b", "name":"b","children":[
{ "id":"b", "name":"b"},
{ "id":"c", "name":"c"},
{ "id":"d", "name":"d"}
]
},
{ "id":"e", "name":"e","children":[
{ "id":"f", "name":"f"},
{ "id":"g", "name":"g"},
{ "id":"h", "name":"h"}
]
},
]
}
]
the content of my json file is loaded in result[0]. and when i am calling addPath like :
result[0]=addPath(result[0]);
it shows me an error that "forEach" will not work as it is not the property of object.
Do it with this code :-
function addPath(obj){
if(!obj.hasOwnProperty('path')){
obj.path = 'home.html';
}
if(obj.hasOwnProperty('children')){
obj.children.forEach(function(obj1){
obj1 = addPath(obj1);
});
}
return obj;
}
r = addPath(r);
I know that my way is not optimum, but it is working:
I append new item through .replace(...) (without loop)
var r = JSON.parse(JSON.stringify(r).replace(new RegExp("\"url\"", 'g'), '"path": "home.html", "url"'));
console.log(r);
var r={
"id": "A",
"name": "Analysis",
"url": "A.html",
"root": true,
"children": [
{
"id": "B",
"name": "Introduction",
"url": "B.html",
"root": true,
"children": [{
"id": "C",
"name": "Creating",
"url": "c.html#I1"
}, {
"id": "D",
"name": "Running",
"url": "d.html#I2"
}]
},
{
"id": "E",
"name": "Transient Analysis",
"url": "E.html",
"root": true,
"children": [{
"id": "F",
"name": "RC",
"url": "F.html#T1"
}, {
"id": "G",
"name": "RLC",
"url": "G.html#T2"
}]
}
]
}
var r = JSON.parse(JSON.stringify(r).replace(new RegExp("\"url\"", 'g'), '"path": "home.html", "url"'));
console.log(r);