I want to search in json data with multiple levels of array. My search list return names of my objects but just from the first level. How could i do return all my object's names regardless their levels ?
In this example : OST, OST details, Apocalpse Now, Arizona Dream, Dexter
Data
<script type="application/json" id="dataMusic">
{
"name":"Music",
"level":"1",
"size":36184,
"children":[
{
"name":"OST",
"level":"2",
"size":1416,
"children":[
{
"name":"OST details",
"level":"3",
"size":1416,
"children":[
{
"name":"Apocalypse Now",
"size":15
},
{
"name":"Arizona Dream",
"size":19
},
{
"name":"Dexter",
"size":20
}
]
}
]
}
]
}
</script>
Function
var dataMusic = document.getElementById('dataMusic').innerHTML;
var dataTree = JSON.parse(dataMusic);
var optArray = [];
for (var i = 0; i < dataTree.children.length - 1; i++) {
optArray.push(dataTree.children[i].name);
}
optArray = optArray.sort();
I try this method Parsing Nested Objects in a Json using JS without success
Function
var optArray = [], Music, OST, OST details;
for (Music in dataTree) {
for (OST in dataTree[Music]) {
for (OST details in dataTree[Music][OST]) {
if (OST details in optArray) {
optArray[OST details].push(dataTree[Music][OST][OST details].name)
} else {
optArray[OST details] = [dataTree[Music][OST][OST details].name]
}
}
}
}
You must use nested loops
for Music.children.length
for OST.children.length
for OST details.children.length
Edit : Function
var optArray = [], Music, OST, OST_details;
for (Music in dataTree) {
for (OST in dataTree[Music]) {
for (OST_details in dataTree[Music][OST]) {
if (OST_details in optArray) {
optArray[OST_details].push(dataTree[Music][OST][OST_details].name)
} else {
optArray[OST_details] = [dataTree[Music][OST][OST_details].name]
}
}
}
}
I got it
var dataMusic = document.getElementById('dataMusic').innerHTML;
var dataTree = JSON.parse(dataMusic);
var result = [];
function getAll( input, target ) {
function parseData( input, target ) {
$.each( input, function ( index, obj ) {
if ( index == target ) {
result.push( obj );
}
else {
switch ( $.type( obj ).toLowerCase() ) {
case "object":
case "array":
parseData( obj, target );
break;
}
}
});
}
parseData( dataTree, "name" );
result = result.sort();
return result;
}
alert(JSON.stringify( getAll( dataTree, "name" )));
Thanks to this post :
Parsing multi-level json ; Demo
Related
I am trying to use the group by function on a JSON array using the inner JSON value as a key as shown below. But unable to read the inner JSON value. Here is my JSON array.
NotificationData = [
{
"eventId":"90989",
"eventTime":"2019-12-11T11:20:53+04:00",
"eventType":"yyyy",
"event":{
"ServiceOrder":{
"externalId":"2434",
"priority":"1"
}
}
},
{
"eventId":"6576",
"eventTime":"2019-12-11T11:20:53+04:00",
"eventType":"yyyy",
"event":{
"ServiceOrder":{
"externalId":"78657",
"priority":"1"
}
}
}
]
GroupBy Logic:
const groupBy = (array, key) => {
return array.reduce((result, currentValue) => {
(result[currentValue[key]] = result[currentValue[key]] || []).push(
currentValue
);
return result;
}, {});
};
const serviceOrdersGroupedByExternalId = groupBy(this.NotificationData, 'event.ServiceOrder.externalId');
//this line of code is not working as
// it is unable to locate the external id value.
Desired output
{ "2434":[{
"eventId":"90989",
"eventTime":"2019-12-11T11:20:53+04:00",
"eventType":"yyyy",
"event":{
"ServiceOrder":{ "priority":"1" }
}
}],
"78657":[{
"eventId":"6576",
"eventTime":"2019-12-11T11:20:53+04:00",
"eventType":"yyyy",
"event":{
"ServiceOrder":{ "priority":"1" }
}
}]
}
Does this solves your purpose?
let group = NotificationData.reduce((r, a) => {
let d = r[a.event.ServiceOrder.externalId] = [...r[a.event.ServiceOrder.externalId] || [], a];
return r;
}, {});
console.log(group);
Try like this:
result = {};
constructor() {
let externalIds = this.NotificationData.flatMap(item => item.event.ServiceOrder.externalId);
externalIds.forEach(id => {
var eventData = this.NotificationData.filter(
x => x.event.ServiceOrder.externalId == id
).map(function(item) {
delete item.event.ServiceOrder.externalId;
return item;
});
this.result[id] = eventData;
});
}
Working Demo
There is a way to map json objects in react-native? For example, let's say I receive the following object:
{
"dados": {
"ultimaAtualizacao": {
"nome": "Lala"
}
"nascimento": "01/01/2001"
}
}
I want to map it like this:
{
"data": {
"lastUpdate": {
"name": "Lala"
}
"dob": "01/01/2001"
}
}
Considering that fetch returns the first object, this would be possible doing the following code:
myService.get(url).then(response => this.mapObject(response, []));
//Considering state is initialized and I have the mapedEntity to return correct properties
mapObject(jsonObject, parentProperty) {
for (let property in jsonObject) {
if (Array.isArray(jsonObject[property])) {
this.mapArray(jsonObject[property], [...parentProperty,property]); //Would be something like mapObject function
} else if (typeof jsonObject[property] === 'object') {
this.mapObject(jsonObject[property],[...parentProperty,property]);
} else {
let prop = this.state;
for(let k of parentProperty) {
prop = prop[mapedEntity[k]];
}
prop[entidadeMapeada[property]] = jsonObject[property];
}
}
}
There is someway simplier to achieve this?
I found many solutions to find depth of nodes in a nested json file. but it throws me an error "maximum recursion depth exceeded "
when it set maximum recursion limit, it says "process exceeded with some error code"
As a part of my problem, I also need to find out key names of each node in the json file.
example json :
"attachments": {
"data": [
{
"media": {
"image": {
"height": 400,
"src": "https://scontent.xx.fbcdn.net/v/t1.0-1/10250217_10152130974757825_8645405213175562082_n.jpg?oh=904c1785fc974a3208f1d18ac07d59f3&oe=57CED94D",
"width": 400
}
},
"target": {
"id": "74286767824",
"url": "https://www.facebook.com/LAInternationalAirport/"
},
"title": "Los Angeles International Airport (LAX)",
"type": "map",
"url": "https://www.facebook.com/LAInternationalAirport/"
}
]
}
the output should be:
nodes:
[data [media [image[height,width,src]], target[id,url], title, type, url]]
depth: 4
If anyone else came here and found that the accepted answer does not work because Object.keys() for a string returns an array of each character of string and thus for either large objects or objects with large strings it just fails.
Here is something that works ->
function getDepth(obj){
if(!obj || obj.length===0 || typeof(obj)!=="object") return 0;
const keys = Object.keys(obj);
let depth = 0;
keys.forEach(key=>{
let tmpDepth = getDepth(obj[key]);
if(tmpDepth>depth){
depth = tmpDepth;
}
})
return depth+1;
}
Exmaple - https://jsfiddle.net/95g3ebp7/
Try the following function:
const getDepth = (
// eslint-disable-next-line #typescript-eslint/no-explicit-any
obj: Record<string, any>,
tempDepth?: number
): number => {
let depth = tempDepth ? tempDepth : 0;
if (obj !== null) {
depth++;
if (typeof obj === 'object' && !Array.isArray(obj)) {
const keys = Object.keys(obj);
if (keys.length > 0)
depth = Math.max(
...keys.map((key) => {
return getDepth(obj[key], depth);
})
);
} else if (Array.isArray(obj)) {
if (obj.length > 0)
depth = Math.max(
...obj.map((item) => {
return getDepth(item, depth);
})
);
}
}
return depth;
};
If you try this, I believe you have to get 7.
console.log(getDepth({
a: {
b: { a: [{ a: { a: [] } }] }
}
}));
function geth(obj) {
var depth = 0;
var k = Object.keys(obj);
console.log(k);
for (var i in k) {
var tmpDepth = geth(obj[k[i]]);
if (tmpDepth > depth) {
depth = tmpDepth
}
}
return 1 + depth;
}
I have a json like this
{"Beauty_Personal_Care": {
"listingVersions": {
"v1": {
"get": "http://affiliate-feeds.snapdeal.com/feed/api/category/v1:586:680986904635?expiresAt=1455143400082&signature=gtvuofdhkeqxipadfzyf"
}
}
},
"Eyewear": {
"listingVersions": {
"v1": {
"get": "http://affiliate-feeds.snapdeal.com/feed/api/category/v1:473:630636448881?expiresAt=1455143400082&signature=gtvuofdhkeqxipadfzyf"
}
}
}
}
I want to get key value and objects of key value separately in node js backend.
Expected result:
name="Beauty_Personal_Care";
url="http://affiliate-feeds.snapdeal.com/feed/api/category/v1:586:680986904635?expiresAt=1455143400082&signature=gtvuofdhkeqxipadfzyf";
var json = {}; // your json
var result = [];
Object.keys(json).forEach(function (name) {
var data = {
name: name
};
data.url = json[name].listingVersions.v1.get;
result.push(data);
});
console.log(result);
I have json answer like
{
"bField":"some data",
"aField":"some data",
"cField":"some data",
"dField":{
"b1Field":"some data",
"c1Field":"some data",
"a1Field":"some data"
}
}
and I want to get that json, sorted by field name
{
"aField":"some data",
"bField":"some data",
"cField":"some data",
"dField":{
"a1Field":"some data",
"b1Field":"some data",
"c1Field":"some data"
}
}
I use Gson on server for create json, so my first question: can Gson sort fields by name? Or tell me of some sites or JavaScript libraries, which can convert json to json with sorted by name fields?
UPDATED:
I modify 'sortObject' function by #dariogriffo for sorting nested object fields:
function sortObject(o) {
var sorted = {},
key, a = [];
for (key in o) {
if (o.hasOwnProperty(key)) {
if (o[key]!=null && typeof o[key] === 'object'){
o[key] = sortObject(o[key]);
}
a.push(key);
}
}
a.sort();
for (key = 0; key < a.length; key++) {
sorted[a[key]] = o[a[key]];
}
return sorted;
};
Now is work good for me.
you can try this on your javascript side
function sortObject(o) {
var sorted = {},
key, a = [];
for (key in o) {
if (o.hasOwnProperty(key)) {
a.push(key);
}
}
a.sort();
for (key = 0; key < a.length; key++) {
sorted[a[key]] = o[a[key]];
}
return sorted;
}
var q = {
bField:'some data',
aField:'some data',
cField:'some data',
dField:{
b1Field:'some data',
c1Field:'some data',
a1Field:'some data'
}
};
var p = sortObject(q);
console.log(p);