Related
i have a json returned from an api that shows latest discussions from a forum..
the url that display the json output is like:
https://example.com/api/discussions?isApproved=true&exists=true&sort=-lastPostedAt
and this is the json output:
"links": {
"first": "http://localhost/flarum/public/api/discussions?isApproved=true\u0026exists=true\u0026sort=-lastPostedAt",
"next": "http://localhost/flarum/public/api/discussions?isApproved=true\u0026exists=true\u0026sort=-lastPostedAt\u0026page%5Boffset%5D=20"
},
"data": [
{
"type": "discussions",
"id": "46",
"attributes": {
"title": "footer",
"slug": "46-footer",
"commentCount": 1,
"participantCount": 1,
"createdAt": "2021-09-20T07:14:18+00:00",
"lastPostedAt": "2021-09-20T07:14:18+00:00",
"lastPostNumber": 1,
"canReply": true,
"canRename": true,
"canDelete": true,
"canHide": true,
"lastReadAt": "2021-09-20T07:14:20+00:00",
"lastReadPostNumber": 1,
"isApproved": true,
"canTag": true,
"subscription": null,
"isLocked": false,
"canLock": true
},
"relationships": { "user": { "data": { "type": "users", "id": "1" } }, "lastPostedUser": { "data": { "type": "users", "id": "1" } }, "tags": { "data": [{ "type": "tags", "id": "2" }] } }
},
{
"type": "discussions",
"id": "45",
"attributes": {
"title": "fhgfhfg",
"slug": "45-fhgfhfg",
"commentCount": 2,
"participantCount": 1,
"createdAt": "2021-09-19T16:07:37+00:00",
"lastPostedAt": "2021-09-19T23:04:00+00:00",
"lastPostNumber": 2,
"canReply": true,
"canRename": true,
"canDelete": true,
"canHide": true,
"lastReadAt": "2021-09-19T23:04:02+00:00",
"lastReadPostNumber": 2,
"isApproved": true,
"canTag": true,
"subscription": null,
"isLocked": false,
"canLock": true
},
"relationships": { "user": { "data": { "type": "users", "id": "1" } }, "lastPostedUser": { "data": { "type": "users", "id": "1" } }, "tags": { "data": [{ "type": "tags", "id": "2" }] } }
},
{
"type": "discussions",
"id": "39",
"attributes": {
"title": "Discussion",
"slug": "39-discussion",
"commentCount": 21,
"participantCount": 1,
"createdAt": "2021-05-22T11:06:43+00:00",
"lastPostedAt": "2021-09-04T12:49:32+00:00",
"lastPostNumber": 28,
"canReply": true,
"canRename": true,
"canDelete": true,
"canHide": true,
"lastReadAt": "2021-09-04T12:49:34+00:00",
"lastReadPostNumber": 28,
"isApproved": true,
"canTag": true,
"subscription": null,
"isLocked": false,
"canLock": true
},
"relationships": { "user": { "data": { "type": "users", "id": "1" } }, "lastPostedUser": { "data": { "type": "users", "id": "1" } }, "tags": { "data": [{ "type": "tags", "id": "1" }] } }
}
what i want to do is to have something like "related content" based on a discussion title. For example if i have this title "lets talk about cars", the json must shows all the discussions related to this title.
is this possible?
You can take the data from json and just filter the content inside
const filteredResults = yourJsonResponse.data.filter(item => item.attributes.title === 'lets talk about cars')
This won't be a good idea. as you're getting paginated list with limit(like per page 20/30). if you're using js you can use js filter for getting related content. But as i said. that filer will be done based on your current page data, not all data. it's better to use another api end for related content from large data..
I have two JSON strings as shown below:
source = [
{
"name": "test1",
"values": ["User Support"],
"enabled": false
},
{
"name": "test2",
"values": ["M"],
"enabled": true
},
{
"name": "test3",
"values": ["CA"],
"enabled": false
}
]
target = [{
"name": "test1",
"values": [{
"value": "User Support",
"selected": false
},
{
"value": "Engineering",
"selected": false
},
{
"value": "Implementation",
"selected": false
}
],
"enabled": false
},
{
"name": "test2",
"values": [{
"value": "M",
"selected": false
},
{
"value": "F",
"selected": false
}
],
"notEnabled": false
},
{
"name": "test3",
"values": [{
"value": "CA",
"selected": false
},
{
"value": "EN",
"selected": false
}
],
"enabled": false
}
]
I want to merge both these JSON strings into target and the resultant should look like:
target = [{
"name": "test1",
"values": [{
"value": "User Support",
"selected": true
},
{
"value": "Engineering",
"selected": false
},
{
"value": "Implementation",
"selected": false
}
],
"enabled": false
},
{
"name": "test2",
"values": [{
"value": "M",
"selected": true
},
{
"value": "F",
"selected": false
}
],
"enabled": true
},
{
"name": "test3",
"values": [{
"value": "CA",
"selected": true
},
{
"value": "EN",
"selected": false
}
],
"enabled": false
}
]
So, what I am trying to do is search in target string for name as test1, test2.... and then set the selected field as true if the value is found in source JSON string. Same is the case for enabled field.
First thing that comes to my mind is to use nested for each loops and check for the keys.
Is there any other better way to do this in Javascript?
Note that there could be other keys present inside target string, but we don't bother about them unless they are present in source string.
If you don't mind lodash:
const _ = require('lodash');
const sourceJSON = '[{"name":"test1","values":["User Support"],"enabled":false},{"name":"test2","values":["M"],"enabled":true},{"name":"test3","values":["CA"],"enabled":false}]';
const targetJSON = '[{"name":"test1","values":[{"value":"User Support","selected":false}, {"value":"Engineering","selected":false},{"value":"Implementation","selected":false}],"enabled":false},{"name":"test2","values":[{"value":"M","selected":false}, {"value":"F","selected":false} ],"notEnabled":false},{ "name":"test3","values": [{"value":"CA","selected":false},{"value":"EN","selected":false}],"enabled":false}]';
const source = JSON.parse(sourceJSON);
const target = JSON.parse(targetJSON);
const sourceNormalized = source.map((obj) => (
{ ...obj, values: [{value: obj.values[0], selected: true}] }
));
const merged = _.defaultsDeep(sourceNormalized, target);
console.dir(merged, {depth: null});
// [ { name: 'test1',
// values: [
// { value: 'User Support', selected: true },
// { value: 'Engineering', selected: false },
// { value: 'Implementation', selected: false }
// ],
// enabled: false
// },
// { name: 'test2',
// values: [
// { value: 'M', selected: true },
// { value: 'F', selected: false }
// ],
// enabled: true,
// notEnabled: false
// },
// { name: 'test3',
// values: [
// { value: 'CA', selected: true },
// { value: 'EN', selected: false }
// ],
// enabled: false} ]
result = JSON.stringify(merged);
The previous answer using lodash is a very good approach. In case you are in a situation such as myself (stuck working on a code-base where packages, including lodash, are difficult to get approved-for-use), here is an approach using Vanilla-javascript (+ JSON.stringify):
const delta = [{
"name": "test1",
"values": ["User Support"],
"enabled": false
},
{
"name": "test2",
"values": ["M"],
"enabled": true
},
{
"name": "test3",
"values": ["CA"],
"enabled": false
}
];
const orig = [{
"name": "test1",
"values": [{
"value": "User Support",
"selected": false
},
{
"value": "Engineering",
"selected": false
},
{
"value": "Implementation",
"selected": false
}
],
"enabled": false
},
{
"name": "test2",
"values": [{
"value": "M",
"selected": false
},
{
"value": "F",
"selected": false
}
],
"notEnabled": false
},
{
"name": "test3",
"values": [{
"value": "CA",
"selected": false
},
{
"value": "EN",
"selected": false
}
],
"enabled": false
}
];
const getTargetJSON = (delta, orig, debug = true) => { // method signature
const deltaMapper = delta.reduce((f, i) => ({
...f,
[i.name]: {
values: [...i.values],
enabled: i.enabled
}
}), {});
const target = orig.map(itm => ({
...itm,
values: itm.values.map(it2 => ({
...it2,
selected: deltaMapper[itm.name].values.includes(it2.value) || false
})),
enabled: deltaMapper[itm.name].enabled || false
}));
debug && console.log('Merged Target:\n', target);
return JSON.stringify(target);
};
getTargetJSON(delta, orig); // method call
Approach / Explanation:
We breakdown the problem into smaller ones.
First, generate a map using the source (named 'delta' in
code-snippet)
Next, iterate through the target (named 'orig') and utilize the
map (created above) to determine whether value is 'selected' and
item is 'enabled'.
I cant wrap my head on how to fetch value from a key Value json pair.
My JSON looks like this:
data= [
{
"flowId": 7079,
"flowName": "jackson-demo",
"version": 1,
"CreatedDate": "2020-04-02",
"UpdateDate": "",
"LastRunDate": "2020-04-02",
"active": false,
"properties": [
{
"id": 7080,
"key": "country",
"value": "in",
"category": "General"
},
{
"id": 7081,
"key": "source",
"value": "hive",
"category": "General"
}
]
},
{
"flowId": 7079,
"flowName": "jackson-demo",
"version": 1,
"CreatedDate": "2020-04-02",
"UpdateDate": "",
"LastRunDate": "2020-04-02",
"active": false,
"properties": [
{
"id": 7080,
"key": "country",
"value": "au",
"category": "General"
},
{
"id": 7081,
"key": "source",
"value": "aws",
"category": "General"
}
]
}
]
How do I get value of Country or Source.
I am able to iterate and get value of all the Properties array using below code but how do I get value of only country from each Array Objects.
data.forEach(function(obj)
{
console.log(obj.properties);
});
Use a basic forEach loop to iterate over items.
EDIT:
To print all values
data.forEach((arrayItem) => {
arrayItem.properties.forEach(item => {
console.log(item);
});
});
var data = [{
flowId: 7079,
flowName: "jackson-demo",
version: 1,
CreatedDate: "2020-04-02",
UpdateDate: "",
LastRunDate: "2020-04-02",
active: false,
properties: [{
id: 7080,
key: "country",
value: "in",
category: "General"
},
{
id: 7081,
key: "source",
value: "hive",
category: "General"
}
]
},
{
flowId: 7079,
flowName: "jackson-demo",
version: 1,
CreatedDate: "2020-04-02",
UpdateDate: "",
LastRunDate: "2020-04-02",
active: false,
properties: [{
id: 7080,
key: "country",
value: "au",
category: "General"
},
{
id: 7081,
key: "source",
value: "aws",
category: "General"
}
]
}
];
data.forEach(function(arrayItem, i) {
console.log(arrayItem.properties[i]);
});
data.forEach((arrayItem, i) => {
arrayItem.properties.forEach(item => {
console.log(item);
});
});
Basically, data is an array so first you have to access the first element before accessing the properties object. And then using forEach you can iterate through it and access the values.
data = [{
"flowId": 7079,
"flowName": "jackson-demo",
"version": 1,
"CreatedDate": "2020-04-02",
"UpdateDate": "",
"LastRunDate": "2020-04-02",
"active": false,
"properties": [{
"id": 7080,
"key": "country",
"value": "in",
"category": "General"
},
{
"id": 7081,
"key": "source",
"value": "hive",
"category": "General"
}
]
},
{
"flowId": 7079,
"flowName": "jackson-demo",
"version": 1,
"CreatedDate": "2020-04-02",
"UpdateDate": "",
"LastRunDate": "2020-04-02",
"active": false,
"properties": [{
"id": 7080,
"key": "country",
"value": "au",
"category": "General"
},
{
"id": 7081,
"key": "source",
"value": "aws",
"category": "General"
}
]
}
];
var array = Object.keys(data);
array.forEach(i => {
properties = data[i].properties; //gets the properties array object from data
properties.forEach(obj => { //gets each object within the properties array
console.log(obj.key);
console.log(obj.value);
})
})
For every property object you iterate, create an empty object={ }
obj[propertyObj["key"]]=propertyObj["value"]
after this return the object.
Run the following code snippet to verify
let data= [{"flowId": 7079,"flowName": "jackson-demo","version": 1,"CreatedDate": "2020-04-02","UpdateDate": "","LastRunDate": "2020-04-02","active": false,
"properties": [{"id": 7080,"key": "country","value": "in","category": "General"},{"id": 7081,"key": "source","value": "hive","category": "General"}]},{"flowId": 7079,"flowName": "jackson-demo", "version": 1, "CreatedDate": "2020-04-02","UpdateDate": "","LastRunDate": "2020-04-02","active": false,
"properties": [{ "id": 7080,"key":"country","value": "au","category":"General"},{"id": 7081,"key": "source","value":"aws","category": "General"}]
}]
console.log(data.map(item =>{
let obj={};
for (const propertyObj of item.properties)
obj[propertyObj["key"]]=propertyObj["value"]
return obj;
}));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Your JSON structure is as below:
data = array node with multiple object nodes,
properties = array node with multiple object nodes within each "data" object node,
key/value = simple string json node for each "property" object node.
So, first we need to iterate through "data" array node and for each data object node, fetch the "properties" array node and retrieve "key" and "value" for each property object node.
var data= [
{
"flowId": 7079,
"flowName": "jackson-demo",
"version": 1,
"CreatedDate": "2020-04-02",
"UpdateDate": "",
"LastRunDate": "2020-04-02",
"active": false,
"properties": [
{
"id": 7080,
"key": "country",
"value": "in",
"category": "General"
},
{
"id": 7081,
"key": "source",
"value": "hive",
"category": "General"
}
]
},
{
"flowId": 7079,
"flowName": "jackson-demo",
"version": 1,
"CreatedDate": "2020-04-02",
"UpdateDate": "",
"LastRunDate": "2020-04-02",
"active": false,
"properties": [
{
"id": 7080,
"key": "country",
"value": "au",
"category": "General"
},
{
"id": 7081,
"key": "source",
"value": "aws",
"category": "General"
}
]
}
];
data.forEach(dataItem=>{
dataItem.properties.forEach(property=>{
document.write("key: "+property.key+" ,");
document.write("value: "+property.value+"<br>");
});
});
I have an array like that:
[
{"id":"one","name":"school", "selected": false, "children":[
{"id":"1","name":"school", "selected": false},
{"id":"2","name":"student", "selected": true},
{"id":"3","name":"teacher", "selected": false}
]},
{"name":"two","name":"school", "selected": false, "children":[
{"id":"1","name":"school", "selected": true},
{"id":"3","name":"teacher", "selected": false}
]},
{"name":"three","name":"school", "selected": true, "children":[
{"id":"1","name":"school", "selected": false},
{"id":"2","name":"student", "selected": false}
]}
]
How I can filter on that array to get only the name of the object that has the field select as true?
The output should be an array for the name of objects:
[student, school, school]
I tried this using lodash:
_.filter(array, {selected: true}).map(function (division) {
return array.name;
});
But this always return the root objects, never the objects that are inside the children.
You could just iterate and look if the wanted property selected is true, the push to result, if there is a children, iterate the children.
This works with Array#forEach
var data = [{ "id": "one", "name": "school", "selected": false, "children": [{ "id": "1", "name": "school", "selected": false }, { "id": "2", "name": "student", "selected": true }, { "id": "3", "name": "teacher", "selected": false }] }, { "name": "two", "name": "school", "selected": false, "children": [{ "id": "1", "name": "school", "selected": true }, { "id": "3", "name": "teacher", "selected": false }] }, { "name": "three", "name": "school", "selected": true, "children": [{ "id": "1", "name": "school", "selected": false }, { "id": "2", "name": "student", "selected": false }] }],
result = [];
data.forEach(function iter(o) {
o.selected && result.push(o.name);
(o.children || []).forEach(iter);
});
console.log(result);
The same with lodash _.forEach
var data = [{ "id": "one", "name": "school", "selected": false, "children": [{ "id": "1", "name": "school", "selected": false }, { "id": "2", "name": "student", "selected": true }, { "id": "3", "name": "teacher", "selected": false }] }, { "name": "two", "name": "school", "selected": false, "children": [{ "id": "1", "name": "school", "selected": true }, { "id": "3", "name": "teacher", "selected": false }] }, { "name": "three", "name": "school", "selected": true, "children": [{ "id": "1", "name": "school", "selected": false }, { "id": "2", "name": "student", "selected": false }] }],
result = [];
_.forEach(data, function iter(o) {
o.selected && result.push(o.name);
_.forEach(o.children, iter);
});
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
A version with Array#reduce.
var data = [{ "id": "one", "name": "school", "selected": false, "children": [{ "id": "1", "name": "school", "selected": false }, { "id": "2", "name": "student", "selected": true }, { "id": "3", "name": "teacher", "selected": false }] }, { "name": "two", "name": "school", "selected": false, "children": [{ "id": "1", "name": "school", "selected": true }, { "id": "3", "name": "teacher", "selected": false }] }, { "name": "three", "name": "school", "selected": true, "children": [{ "id": "1", "name": "school", "selected": false }, { "id": "2", "name": "student", "selected": false }] }],
result = data.reduce(function iter(r, o) {
o.selected && r.push(o.name);
return (o.children || []).reduce(iter, r);
}, []);
console.log(result);
And another version with lodash _.reduce.
var data = [{ "id": "one", "name": "school", "selected": false, "children": [{ "id": "1", "name": "school", "selected": false }, { "id": "2", "name": "student", "selected": true }, { "id": "3", "name": "teacher", "selected": false }] }, { "name": "two", "name": "school", "selected": false, "children": [{ "id": "1", "name": "school", "selected": true }, { "id": "3", "name": "teacher", "selected": false }] }, { "name": "three", "name": "school", "selected": true, "children": [{ "id": "1", "name": "school", "selected": false }, { "id": "2", "name": "student", "selected": false }] }],
result = _.reduce(data, function iter(r, o) {
o.selected && r.push(o.name);
return _.reduce(o.children, iter, r);
}, []);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
array
.reduce((a, i) => [...a, i, ...i.childs], [])//flatten array
.filter(i => i.selected)//filter with selected===true
.map(i => i.name));//map to name
console.log([{
"id": "one",
"name": "school",
"selected": false,
"childs": [{
"id": "1",
"name": "school",
"selected": false
}, {
"id": "2",
"name": "student",
"selected": true
}, {
"id": "3",
"name": "teacher",
"selected": false
}]
}, {
"name": "two",
"name": "school",
"selected": false,
"childs": [{
"id": "1",
"name": "school",
"selected": true
}, {
"id": "3",
"name": "teacher",
"selected": false
}]
}, {
"name": "three",
"name": "school",
"selected": true,
"childs": [{
"id": "1",
"name": "school",
"selected": false
}, {
"id": "2",
"name": "student",
"selected": false
}]
}].reduce((a, i) => [...a, i, ...i.childs], []).filter(i => i.selected).map(i => i.name));
You could use this functional programming style ES6 solution:
function sel(array) {
return (array || []).reduce ( (acc, o) =>
(o.selected ? acc.concat(o.name) : acc).concat(sel(o.childs)), [] );
}
function sel(array) {
return (array || []).reduce ( (acc, o) =>
(o.selected ? acc.concat(o.name) : acc).concat(sel(o.childs)), [] );
}
// Sample data
var array = [
{"id":"one","name":"school", "selected": false, "childs":[
{"id":"1","name":"school", "selected": false},
{"id":"2","name":"student", "selected": true},
{"id":"3","name":"teacher", "selected": false}
]},
{"name":"two","name":"school", "selected": false, "childs":[
{"id":"1","name":"school", "selected": true},
{"id":"3","name":"teacher", "selected": false}
]},
{"name":"three","name":"school", "selected": true, "childs":[
{"id":"1","name":"school", "selected": false},
{"id":"2","name":"student", "selected": false}
]}
];
// Extract
var result = sel(array);
// Ooutput result
console.log(result);
You can use Array.prototype.map(), Array.prototype.filter()
var arr = [{
"id": "one",
"name": "school",
"selected": false,
"childs": [{
"id": "1",
"name": "school",
"selected": false
}, {
"id": "2",
"name": "student",
"selected": true
}, {
"id": "3",
"name": "teacher",
"selected": false
}]
}, {
"name": "two",
"name": "school",
"selected": false,
"childs": [{
"id": "1",
"name": "school",
"selected": true
}, {
"id": "3",
"name": "teacher",
"selected": false
}]
}, {
"name": "three",
"name": "school",
"selected": true,
"childs": [{
"id": "1",
"name": "school",
"selected": false
}, {
"id": "2",
"name": "student",
"selected": false
}]
}];
var res = arr.map(el =>
(el.selected && el || el.childs.filter(child =>
child.selected
)[0]).name
);
console.log(res);
Well, you should consider the complexity of the script you are trying to build. This is a nested linear algorithm (see https://en.wikipedia.org/wiki/Linear_search) since you have to touch every single element in the array to create the new data structure with the selected elements, which can be very slow if that array size increases.
What you might want to do instead, is to modify the method that toggles the selected property, and copy that 'selected' object to a new selectedElements array.
However, if you are required to do what you asked, and you only want UNIQUE results, check this out:
var data = [
{"id":"one","name":"school", "selected": false, "childs":[
{"id":"1","name":"school", "selected": false},
{"id":"2","name":"student", "selected": true},
{"id":"3","name":"teacher", "selected": false}
]},
{"name":"two","name":"school", "selected": false, "childs":[
{"id":"1","name":"school", "selected": true},
{"id":"3","name":"teacher", "selected": false}
]},
{"name":"three","name":"school", "selected": true, "childs":[
{"id":"1","name":"school", "selected": false},
{"id":"2","name":"student", "selected": false}
]}
],
selectedElements = [];
data.map(function(row, i){
if (row.selected) {
if (selectedElements.indexOf(row.name) == - 1)
selectedElements.push(row.name);
}
else{
row.childs.map(function(childRow, ii) {
if (childRow.selected) {
if (selectedElements.indexOf(childRow.name) == - 1)
selectedElements.push(childRow.name);
}
})
}
});
console.log(selectedElements);
Add a line before your lodash _.filter
array = _.flatten(array.map(x => [x].concat(x.childs)))
so it will take the childs.
A classic recursive solution with arrow functions
var result = [];
var recursiveSearch = arr => {
if (Array.isArray(arr)) {
arr.forEach(x => {
if (x.selected === true) result.push(x.name);
if (Array.isArray(x.childs)) recursiveSearch(x.childs);
});
}
}
recursiveSearch(data);
console.log (result);
I am parsing the JSON object. I want to set value which is stored in session against id. I have this JSON:
[
{
"id": "a",
"text": "a",
"icon": true,
"li_attr": {
"id": "a"
},
"a_attr": {
"href": "#"
},
"state": {
"loaded": true,
"opened": false,
"selected": false,
"disabled": false
},
"data": {
},
"children": [
]
},
{
"id": "b",
"text": "b\n ",
"icon": true,
"li_attr": {
"id": "b"
},
"a_attr": {
"href": "#"
},
"state": {
"loaded": true,
"opened": false,
"selected": false,
"disabled": false
},
"data": {
},
"children": [
{
"id": "b-a-1",
"text": "b-a",
"icon": true,
"li_attr": {
"id": "b-a-1"
},
"a_attr": {
"href": "#"
},
"state": {
"loaded": true,
"opened": false,
"selected": false,
"disabled": false
},
"data": {
},
"children": [
]
},
{
"id": "b-b-2",
"text": "b-b\n ",
"icon": true,
"li_attr": {
"id": "b-b-2"
},
"a_attr": {
"href": "#"
},
"state": {
"loaded": true,
"opened": false,
"selected": false,
"disabled": false
},
"data": {
},
"children": [
{
"id": "b-b-a",
"text": "b-b-a",
"icon": true,
"li_attr": {
"id": "b-b-a"
},
"a_attr": {
"href": "#"
},
"state": {
"loaded": true,
"opened": false,
"selected": false,
"disabled": false
},
"data": {
},
"children": [
]
},
{
"id": "b-b-b",
"text": "b-b-b",
"icon": true,
"li_attr": {
"id": "b-b-b"
},
"a_attr": {
"href": "#"
},
"state": {
"loaded": true,
"opened": false,
"selected": false,
"disabled": false
},
"data": {
},
"children": [
]
}
]
}
]
},
{
"id": "c-1",
"text": "c\n ",
"icon": true,
"li_attr": {
"id": "c-1"
},
"a_attr": {
"href": "#"
},
"state": {
"loaded": true,
"opened": false,
"selected": false,
"disabled": false
},
"data": {
},
"children": [
{
"id": "not-c-a-1",
"text": "c-a",
"icon": true,
"li_attr": {
"id": "not-c-a-1"
},
"a_attr": {
"href": "#"
},
"state": {
"loaded": true,
"opened": false,
"selected": false,
"disabled": false
},
"data": {
},
"children": [
]
},
{
"id": "not-c-b-2",
"text": "b-b",
"icon": true,
"li_attr": {
"id": "not-c-b-2"
},
"a_attr": {
"href": "#"
},
"state": {
"loaded": true,
"opened": false,
"selected": false,
"disabled": false
},
"data": {
},
"children": [
]
}
]
}
]
I want to make same type array having object. Inside the object there might be possibility of nested objects. I just want to set value against it id.
Can we get the information of children? If there are children, I need to set value. Here is my fiddle:
http://jsfiddle.net/fuu94/91/
$('#json').click(function(){
var json_list=$('#tree').jstree(true).get_json(); console.log(json_list.length);
for(var i=0;i<json_list.length;i++){
var obj={};
alert(json_list[i].id)
obj=sessionStorage.getItem(json_list[i].id);
arr[i]=obj;
}
console.log(arr)
})
});
Expected output is:
[
{
"a": "value_a",
"arr": [
]
},
{
"b": "value_b",
"arr": [
{
"b-a-1": "value_b-a-1",
"arr": [
]
},
{
"b-b-1": "value_b-b-2",
"arr": [
{
"b-b-a": "value_b-b-a",
"arr": [
]
},
{
"b-b-b": "value_b-b-b",
"arr": [
]
}
]
}
]
},
{
"c-1": "value_c-1",
"arr": [
{
"not-c-a-1": "value_not-c-a-1",
"arr": [
]
},
{
"not-c-b-2": "value_not-c-b-2",
"arr": [
]
}
]
}
]
You could use a reviver function that you pass to JSON.parse.
JSFIDDLE
var json = JSON.stringify([{ id: 'root', children: [ { id: 'nested' } ]}]);
var p = JSON.parse(json, function (k, v) {
if (!k) return v;
if (k === 'id' || k === 'children') return v;
if (+k == k && typeof v === 'object' && v != null && 'id' in v) {
v[v.id] = 'value_' + v.id;
delete v.id;
if (v.children) v.arr = v.children;
delete v.children;
return v;
}
});
JSON.stringify(p); //[{"root":"value_root","arr":[{"nested":"value_nested"}]}]
EDIT: I tried to make the code more robust by using a different approach, but it did not work as expected because the children key did not always came before we started to iterate over the array. Have a look at the edit history, perhaps I overlooked something.
Assuming that "b-b-1": "value_b-b-2" in the expected output is a type and really should be "b-b-2": "value_b-b-2" it should be very easy to map the original array to the expected output.
Use the map method on arrays (or, if you need to support older browsers, use the map implementation of some library you are using (e.g. jQuery or Underscore).
For each of the items in your array, you need to create an item which has two properties. The first property should be named according to the value of the id property of the input object and the value of the property seems like it should be the literal value_ followed by the value of the id property from the input object.
Furthermore, each item should also have an arr property, which is the result of applying our item mapping function to the items in the children array.
So the code could look something like
function mapItem(inputItem){
var item = {};
item[inputItem.id] = "value_" + inputItem.id;
item.arr = inputItem.children.map(mapItem);
return item;
};
var results = originalArray.map(mapItem);
I have the above mapping function running against your sample data at http://jsfiddle.net/tJ7Kq/