My JSON output is similar to this below object and we have an array values as showing below
const object1 = {
"sublists": {
"item": [{
"line": "1",
"amount": "1200.00",
"id": "227",
"item": "227",
"item_display": "5800520002800",
"quantity": "1"
}
],
"shipping": [{
"line": "1",
"amount": "1200.00",
"id": "227",
"quantity": "1"
}
]
}
}
I am trying to get the name of arrays and values in separate variable as showing below
Array name :item, line: , 1
Array name :item , amount : 1200
Array name :item, id : 227
and so on ...
the array properties can varry depending on the json ouput , im looking for a dynamic script in which i could access the array name and properties
Can someone help me on this ?
try this
function iterateObject(obj, parent) {
if (typeof obj == "object")
if (!Array.isArray(obj))
Object.keys(obj).forEach((prop) => {
if (typeof obj[prop] == "object") iterateObject(obj[prop], prop);
else console.log(`Parent name : ${parent}, ${prop} : ${obj[prop]}`);
});
else
obj.forEach((elem) => {
iterateObject(elem, parent);
});
else console.log(`Parent name : ${parent}, ${parent} : ${obj}`);
}
iterateObject(object1,"sublists");
UPDATE
this is code for your json in comment
iterateObject(object01,"item");
The easy way to achieve the desired outcome is to pass the 'parentKey' to the recursive call:
const object1 = {sublists: {sales_order: [], data: [{"key1": "a", "value": 2 }, {"key1": "b", "value": 4 }], memo: [{"key1": "a", "value": 5 }] } };
function printValues(obj, parentName = null) {
if (Object.prototype.toString.call(obj) === '[object Array]') {
obj.forEach(o => console.log(`Array name: ${parentName}. Key1: ${o.key1}. Value: ${o.value}`));
} else {
for (let k in obj) {
printValues(obj[k], k);
}
}
};
printValues(object1) ;
The first if statement if to check if the varaible is an array or object. Logic taken from:
How do you check if a variable is an array in JavaScript?
Array name: data. Key1: a. Value: 2
Array name: data. Key1: b. Value: 4
Array name: memo. Key1: a. Value: 5
I believe this will solve your problem. I followed the recursive nature of the code you gave and adapted it to make sure it was giving the output you desired. If you have any questions please let me know, and I'll try to address them.
function printValues(obj) {
for (const [objKey, objValue] of Object.entries(
obj
)) {
if (
typeof objValue === 'object' &&
!objValue.length
) {
printValues(objValue);
} else if (
objValue !== undefined &&
objValue.length > 0
) {
for (let i = 0; i < objValue.length; i++) {
const currentObject = objValue[i];
let str = '';
for (const [key, value] of Object.entries(
currentObject
)) {
str += `Array name: ${objKey} , key1: ${key} , value: ${value}\n`;
}
console.log(str);
}
}
}
}
I am trying to convert the keys in JSON to the capital case using Javascript. I am successful to some extent. However, it is not creating the arrays in the correct way. It is inserting numbers before every object inside an array.
Input:
{
"id": "123",
"retweetCheck": {
"result": "OK",
"checks": [
{
"cId": "123"
},
{
"cId": "456"
}
]
},
"tweetCheck": {
"result": "OK",
"cId": "345",
"check": "Fail"
}
}
Code to convert the keys to capital case:
var responseContent = context.getVariable("response.content") || "";
responseContent = JSON.parse(responseContent) || "";
transformedCapitalizedObj = keysToCapitalCase(responseContent);
var finalResponseObj = {
Data: transformedCapitalizedObj
};
context.setVariable("response.content", JSON.stringify(finalResponseObj));
The function
function objEntries(obj) {
const keys = Object.keys(obj);
const keyValuePairs = keys.map(key => {
const value = obj[key];
return [key, value];
});
return keyValuePairs;
}
function keysToCapitalCase(objToProcess) {
if (!objToProcess || typeof objToProcess !== "object") return null;
var finalObj = {};
objToProcess = objEntries(objToProcess);
objToProcess.forEach(function (entry) {
var key = entry[0];
var value = entry[1];
key = key.charAt(0).toUpperCase() + key.slice(1);
if (typeof value == "object" || (value instanceof Array)) {
value = keysToCapitalCase(value);
}
finalObj[key] = value;
});
return finalObj;
}
The output I am getting currently is:
{
"Data":{
"RetweetCheck":{
"Checks":{
"0":{
"CId":"123"
},
"1":{
"CId":"456"
}
},
"Result":"OK"
},
"Id":"123",
"TweetCheck":{
"CId":"345",
"Check":"Fail",
"Result":"OK"
}
}
}
But ideally, the output should look like this:
{
"Data": {
"Id": "123",
"RetweetCheck": {
"Result": "OK",
"Checks": [
{
"CId": "123"
},
{
"CId": "456"
}
]
},
"TweetCheck": {
"Result": "OK",
"CId": "345",
"Check": "Fail"
}
}
}
It is basically inserting a serial number before each object inside an array instead of []. How this can be rectified. Any help will really do wonders.
When you call your function keysToCapitalCase(), first check if you have an array (with ES6, you can do this using Array.isArray()), and if you do, you can map the objects / inner arrays within that array to the result of recursively calling your keysToCapitalize function. Otherwise, if you get a standard object that isn't an array, you can perform your standard object mapping:
const obj = { "id": "123", "retweetCheck": { "result": "OK", "checks": [{ "cId": "123" }, { "cId": "456" } ] }, "tweetCheck": { "result": "OK", "cId": "345", "check": "Fail" } };
function keysToCapitalCase(objToProcess) {
if (!objToProcess || typeof objToProcess !== "object") return null;
if(Array.isArray(objToProcess)) {
return objToProcess.map(obj => keysToCapitalCase(obj));
}
var finalObj = {};
objToProcess = Object.entries(objToProcess); // if you can support it, `Object.entries()` does what `objEntries` does
objToProcess.forEach(function(entry) {
var key = entry[0];
var value = entry[1];
key = key.charAt(0).toUpperCase() + key.slice(1);
if (typeof value == "object") {
value = keysToCapitalCase(value);
}
finalObj[key] = value;
});
return finalObj;
}
var finalResponseObj = {Data: keysToCapitalCase(obj)};
console.log(finalResponseObj);
I would probably write the above method in a similar way, but instead using some inbuilt functions to make it a little more concise, such as .map() and Object.fromEntries():
const obj = { "id": "123", "retweetCheck": { "result": "OK", "checks": [{ "cId": "123" }, { "cId": "456" } ] }, "tweetCheck": { "result": "OK", "cId": "345", "check": "Fail" } };
const cap = str => str.charAt(0).toUpperCase() + str.slice(1);
const keysToCapitalCase = (objToProcess) => {
if (Object(objToProcess) !== objToProcess) return null;
return Array.isArray(objToProcess)
? objToProcess.map(obj => keysToCapitalCase(obj))
: Object.fromEntries(Object.entries(objToProcess).map(([key, val]) => [
cap(key), Object(val) === val ? keysToCapitalCase(val) : val
]));
}
const finalResponseObj = {Data: keysToCapitalCase(obj)};
console.log(finalResponseObj);
As indicated by the {} brackets, instead of the wanted [] brackets you are creating an empty object and not an Array.
To create an Array just change your var finalObj = {}; to var finalObj = [];
with an Array finalObj[key] = value will no longer work, you will now have to use finalObj.push(value)
I want to select specific object properties where they aren't null.
I want to select id and name of this object:
{
"description": "hello",
"title": "Update",
"id": "1",
"name": null
}
expected output:
{
"id": "1",
// no name because it's null
}
I tried to do that using this code:
const { title, description, ...newValues } = values;
console.log(newValues);
You can filter all null elements by converting them to an entries array and then back to an object:
const filteredNewValues = Object.fromEntries(Object.entries(newValues).filter(e => e[1]))
Browser-Support is limited. So use a polyfill if you need to use it in old browsers. See here.
Grab all keys with Object.keys and then using reduce to get the selected property only that is not null.
You can use condition either obj[curr] or obj[curr] !== null
const obj = {
description: "hello",
title: "Update",
id: "1",
name: null,
};
const selected = ["id", "name"];
const result = Object.keys(obj).reduce((acc, curr) => {
if (selected.includes(curr) && obj[curr]) {
acc[curr] = obj[curr];
}
return acc;
}, {});
console.log(result);
let data = {
"description": "hello",
"title": "Update",
"id": "1",
"name": null
}
let filteredData = data.name && data.id ? {id: data.id, name: data.name} : undefined
Okay, let's assume that you want to make it in a dynamic way.
/**
* Get wanted properties of an object
* #param object
* #param {string[]} keys
*/
function cloneObject(obj, keys) {
return keys
.filter(key => obj[key] !== null)
.reduce((newObj, key) => {
newObj[key] = obj[key];
return newObj;
}, {});
}
// here you have your wanted keys
let keys = ['id', 'name'];
let object = {
"description": "hello",
"title": "Update",
"id": "1",
"name": null
};
let newObject = cloneObject(object, keys);
You could create a simple function to extract only non-null passed keys.
var data = {
"description": null,
"title": "Update",
"id": "1",
"name": false
};
function get(data, keys)
{
return keys.reduce((acc, cur) => {
return {...acc, ...(data[cur] !== undefined && data[cur] !== null && {[cur]: data[cur]})}
}, {});
}
console.log(get(data, ["description", "title", "id", "name", "fake"]));
I want to rearrange the following JSON which i am having trouble with. I want to convert a format of JSON object into the other for myself. Any help is appreciated. I Thank you.
From :
[
{"a":1,"b":2,"c":3,"d":4,"name":"chris"},
{"a":11,"b":21,"c":31,"d":41,"name":"chris1"},
{"a":12,"b":22,"c":32,"d":42,"name":"chris2"}
]
To:
[
{
"name": a,
"chris":1,
"chris1":11,
chris2:12
},
{
"name": b,
"chris":2,
"chris1":21,
chris2:22
},
{
"name": c,
"chris":3,
"chris1":31,
chris2:32
},
{
"name": d,
"chris":4,
"chris1":41,
chris2:42
}
]
Here's a snippet you could use
let json = [
{"a":1,"b":"2","c":3,"d":4,"name":"chris"},
{"a":11,"b":"21","c":31,"d":41,"name":"chris1"},
{"a":12,"b":"22","c":32,"d":42,"name":"chris2"}
]
let map = {};
for (const obj of json) {
for( const [key, value] of Object.entries(obj)) {
if (key === "name") continue;
if (typeof map[key] !== "object") {
map[key] = {name: key};
}
const data = map[key];
data[obj.name]= value;
}
}
console.log(map)
I have array and I want to arrange that to object array structure base on same string before dot, I want to create an object array structure to make it editable, so i can fill the value of each data on my array
var arr = ["data",
"data.cell",
"data.cell.celltiming",
"data.cell.celltiming.0",
"data.cell.celltiming.1",
"data.cell.earfcn",
"data.cell.pci",
"data.cell.rsrp",
"data.cell.rsrp.0",
"data.cell.rsrp.1",
"data.cell.rsrp.2",
"data.cell.rsrq",
"data.cell.rsrq.0",
"data.cell.rsrq.1",
"data.cell.rsrq.2",
"data.cell.sinr",
"data.cell.sinr.0",
"data.cell.sinr.1",
"data.cells",
"data.cells.0",
"data.cells.0.ch",
"data.cells.0.ecno",
"data.cells.0.r99",
"data.cells.0.rscp",
"data.cells.0.sc",
"data.cells.1",
"data.cells.1.ch",
"data.cells.1.ecno",
"data.cells.1.r99",
"data.cells.1.rscp",
"data.cells.1.sc",
"data.cells.2",
"data.cells.2.ch",
"data.cells.2.ecno",
"data.cells.2.r99",
"data.cells.2.rscp",
"data.cells.2.sc",
"data.cells.3",
"data.cells.3.ch",
"data.cells.3.ecno",
"data.cells.3.r99",
"data.cells.3.rscp",
"data.cells.3.sc",
"data.id",
"data.mac",
"data.plmn",
"data.rssi",
"data.time",
"deviceID",
"time"]
how can i arrange that to become object array structure
var arr = [ "data": {
"plmn": "",
"id": "",
"time": '',
"cell": {
"rsrp": [
0,
1,
2
],
"rsrq": [
0,
1,
2
],
"earfcn": '',
"pci": '',
"celltiming": [
0,
1
],
"sinr": [
0,
1
]
},
"mac": ""
},
"time": '',
"deviceID": ""]
I want to create an object array so i can fill the value of each key
I've used the following:
Array.prototype.reduce(), accumulating over an empty object {},
A reference (ref) to the accumulator object,
String.prototype.split() to extract individual keys (substrings) from the current string in the array,
Iterating over the keys to progress along the key "chain",
a. If a key doesn't already exist in the accumulator object, create an object at that key, i.e. if (!ref[key]) ref[key] = {}
b. Continue to traverse the accumulator object by re-setting the reference (ref), i.e. ref = ref[key]
Move to the next string in the original array
var arr = ["data",
"data.cell",
"data.cell.celltiming",
"data.cell.celltiming.0",
"data.cell.celltiming.1",
"data.cell.earfcn",
"data.cell.pci",
"data.cell.rsrp",
"data.cell.rsrp.0",
"data.cell.rsrp.1",
"data.cell.rsrp.2",
"data.cell.rsrq",
"data.cell.rsrq.0",
"data.cell.rsrq.1",
"data.cell.rsrq.2",
"data.cell.sinr",
"data.cell.sinr.0",
"data.cell.sinr.1",
"data.cells",
"data.cells.0",
"data.cells.0.ch",
"data.cells.0.ecno",
"data.cells.0.r99",
"data.cells.0.rscp",
"data.cells.0.sc",
"data.cells.1",
"data.cells.1.ch",
"data.cells.1.ecno",
"data.cells.1.r99",
"data.cells.1.rscp",
"data.cells.1.sc",
"data.cells.2",
"data.cells.2.ch",
"data.cells.2.ecno",
"data.cells.2.r99",
"data.cells.2.rscp",
"data.cells.2.sc",
"data.cells.3",
"data.cells.3.ch",
"data.cells.3.ecno",
"data.cells.3.r99",
"data.cells.3.rscp",
"data.cells.3.sc",
"data.id",
"data.mac",
"data.plmn",
"data.rssi",
"data.time",
"deviceID",
"time"
]
var obj = arr.reduce((accumulator, currentValue, currentIndex) => {
let ref = accumulator;
currentValue.split(".").forEach(key => {
if (!ref[key]) ref[key] = {}
ref = ref[key];
})
return accumulator;
}, {})
console.log(JSON.stringify(obj, null, "\t"));
This gets you most of the way. Now all you need to do is:
Traverse the object (first pass), replacing empty objects with empty strings, then
arr.forEach(chain => { // first pass, change empty objects to empty strings
let ref = obj;
chain.split(".").forEach(key => {
if (Object.keys(ref[key]).length === 0) {
ref[key] = ''
} else {
ref = ref[key]
}
})
})
Traverse the object (second pass), checking when all of the keys of an object are numbers and all of the values are empty strings, and replacing this object with an array of the keys.
function keysAreNumbersAndValuesAreEmptyStrings(object) {
let entries = Object.entries(object);
for (let i = 0; i < entries.length; i++) {
let key = entries[i][0], value = entries[i][1];
if(isNaN(Number(key)) || typeof value !== "string" || value.length !== 0) return false;
}
return true;
}
arr.forEach(chain => { // second pass, change objects whose keys are numbers to an array of those keys
let ref = obj;
chain.split(".").forEach(key => {
if (typeof ref[key] === "object" && keysAreNumbersAndValuesAreEmptyStrings(ref[key])) {
ref[key] = Object.keys(ref[key]).map(val => Number(val));
} else {
ref = ref[key]
}
})
})
Complete solution: https://jsfiddle.net/s2attatz/1/
var arr = ["data",
"data.cell",
"data.cell.celltiming",
"data.cell.celltiming.0",
"data.cell.celltiming.1",
"data.cell.earfcn",
"data.cell.pci",
"data.cell.rsrp",
"data.cell.rsrp.0",
"data.cell.rsrp.1",
"data.cell.rsrp.2",
"data.cell.rsrq",
"data.cell.rsrq.0",
"data.cell.rsrq.1",
"data.cell.rsrq.2",
"data.cell.sinr",
"data.cell.sinr.0",
"data.cell.sinr.1",
"data.cells",
"data.cells.0",
"data.cells.0.ch",
"data.cells.0.ecno",
"data.cells.0.r99",
"data.cells.0.rscp",
"data.cells.0.sc",
"data.cells.1",
"data.cells.1.ch",
"data.cells.1.ecno",
"data.cells.1.r99",
"data.cells.1.rscp",
"data.cells.1.sc",
"data.cells.2",
"data.cells.2.ch",
"data.cells.2.ecno",
"data.cells.2.r99",
"data.cells.2.rscp",
"data.cells.2.sc",
"data.cells.3",
"data.cells.3.ch",
"data.cells.3.ecno",
"data.cells.3.r99",
"data.cells.3.rscp",
"data.cells.3.sc",
"data.id",
"data.mac",
"data.plmn",
"data.rssi",
"data.time",
"deviceID",
"time"
]
var obj = arr.reduce((accumulator, currentValue, currentIndex) => {
let ref = accumulator;
currentValue.split(".").forEach(key => {
if (!ref[key]) ref[key] = {}
ref = ref[key];
})
return accumulator;
}, {})
arr.forEach(chain => { // first pass, change empty objects to empty strings
let ref = obj;
chain.split(".").forEach(key => {
if (Object.keys(ref[key]).length === 0) {
ref[key] = ''
} else {
ref = ref[key]
}
})
})
function keysAreNumbersAndValuesAreEmptyStrings(object) {
let entries = Object.entries(object);
for (let i = 0; i < entries.length; i++) {
let key = entries[i][0], value = entries[i][1];
if(isNaN(Number(key)) || typeof value !== "string" || value.length !== 0) return false;
}
return true;
}
arr.forEach(chain => { // second pass, change objects whose keys are numbers to an array of those keys
let ref = obj;
chain.split(".").forEach(key => {
if (typeof ref[key] === "object" && keysAreNumbersAndValuesAreEmptyStrings(ref[key])) {
ref[key] = Object.keys(ref[key]).map(val => Number(val));
} else {
ref = ref[key]
}
})
})
console.log(JSON.stringify(obj, null, "\t"));
/*
{
"data": {
"cell": {
"celltiming": [
0,
1
],
"earfcn": "",
"pci": "",
"rsrp": [
0,
1,
2
],
"rsrq": [
0,
1,
2
],
"sinr": [
0,
1
]
},
"cells": {
"0": {
"ch": "",
"ecno": "",
"r99": "",
"rscp": "",
"sc": ""
},
"1": {
"ch": "",
"ecno": "",
"r99": "",
"rscp": "",
"sc": ""
},
"2": {
"ch": "",
"ecno": "",
"r99": "",
"rscp": "",
"sc": ""
},
"3": {
"ch": "",
"ecno": "",
"r99": "",
"rscp": "",
"sc": ""
}
},
"id": "",
"mac": "",
"plmn": "",
"rssi": "",
"time": ""
},
"deviceID": "",
"time": ""
}
*/