Extract key value pairs from json object and group them - Javascript - javascript

Here is my fiddle : DEMO1
The following function extracts the keys and values and stores it in a new array. This works right for objects(json2 and json3) and not when there is an array of objects (json1)
Is there a way to group a set of key value pairs into an object and then push that object into the array?
Desired output : [{"timestamp":1540457640,"speed":"70"},{"timestamp":1541383353,"speed":"80"},{"timestamp":1541383353,"speed":"70"},{"timestamp":1542256083,"speed":"70"}]
function iterate(obj) {
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
if (typeof obj[property] == "object") {
iterate(obj[property]);
if (isNaN(Number(property))) {
if ((Array.isArray(obj[property])) && (typeof obj[property][0] != "object")) {
simpleArrayKeys[property] = obj[property];
}
}
} else {
if (isNaN(Number(property))) {
simpleArrayKeys[property] = obj[property];
}
}
}
}
}

You can map the data array like so:
var output = json1.data.allStreamingData.map(d => {
return {
"timestamp": d.timestamp,
"speed": d.streamData.speed
}
})
http://jsfiddle.net/fghjtsnm/

Related

Converting object and/or nested array with objects to valid JSON string representation without using JSON.stringify?

I'm having trouble outputting a valid JSON string from an object as input without using JSON.stringify().
Here is my current complete implementation -
var my_json_encode = function(input) {
if(typeof(input) === "string"){
return '"'+input+'"'
}
if(typeof(input) === "number"){
return `${input}`
}
if(Array.isArray(input)) {
const formatedArrayMembers = input.map(value => my_json_encode(value)).join(',');
return `[${formatedArrayMembers}]`;
}
*****Trouble is here*******
if(typeof(input) === "object" && !Array.isArray(input)) {
let temp = "";
for (let [key, value] of Object.entries(input)) {
let val = `${key} : ${value}`;
temp += my_json_encode(val)
}
return `{${temp}}`
}
}
Current input is -> {"key1":"val1","key2":"val2"}
Expected output is -> {"key1":"val1","key2":"val2"}
Current output using object type check in my_json_encode -> {"key1 : val1""key2 : val2"}
I feel that I'm close but something is missing in my logic, I've started at this for to long and need some guidance.
If I can get my object encoder to work, I'm sure I can recursively use it to check more complicated inputs such as:
Expected Output-> [1,"a",{"key1":"value1","key2":null,"key3":[4,"b"],"key5":{"inner1":"innerval1","inner2":9}}]
Related question I asked for an array to JSON string was solved here
The main issue is that you need to put "s around the whole key when iterating over the entries, and call my_json_encode on the value:
"${key}: ${my_json_encode(value)}"
You also need each key-value pair like above to be joined by ,, which can be done easily by mapping each key-value pair to the above sort of string, then .join(',')ing them.
You should also be escaping any "s in the keys or string values with a backslash. Also note that typeof is an operator, not a function - you can use it like typeof someVar:
var my_json_encode = function(input) {
if (typeof input === "string") {
return '"' + input.replace(/"/g, '\\"') + '"'
}
if (typeof input === "number") {
return input;
}
if (Array.isArray(input)) {
const formatedArrayMembers = input.map(my_json_encode).join(',');
return `[${formatedArrayMembers}]`;
}
if (input === null) return 'null';
// then it's a non-array object
const keyValStrArray = Object.entries(input).map(([key, val]) => (
`"${key.replace(/"/g, '\\"')}":${my_json_encode(val)}`
));
return `{${keyValStrArray.join(',')}}`
};
console.log(my_json_encode({ "key1": "val1", "key2": "val2" }));
console.log(my_json_encode([1,"a",{"key1":"value1","key2":null,"key3":[4,"b"],"key5":{"inner1":"innerval1","inner2":9}}]));
For objects, you can make temp an array and just push key: my_json_encode(value) pairs to it, then joining them with , and outputting { and } around the result:
var my_json_encode = function(input) {
if (input === null) {
return "null";
}
if (typeof(input) === "string") {
return `"${input}"`;
}
if (typeof(input) === "number") {
return `${input}`;
}
if (Array.isArray(input)) {
const formatedArrayMembers = input.map(value => my_json_encode(value)).join(',');
return `[${formatedArrayMembers}]`;
}
if (typeof(input) === "object") {
let temp = [];
for (let [key, value] of Object.entries(input)) {
temp.push(`"${key}" : ${my_json_encode(value)}`);
}
return `{${temp.join(', ')}}`;
}
}
console.log(my_json_encode({key1:"val1",key2:3}));
console.log(my_json_encode([1,"a",{"key1":"value1","key2":null,"key3":[4,"b"],"key5":{"inner1":"innerval1","inner2":9}}]));

find value pair in json object using key element

With reference to question posted here use jQuery's find() on JSON object
I have json object in which i'd like to search value of the element if i passed respective key element to it
Json:
{"RESPONSE":{"#xmlns":"","CODE":"0","SECODE":"0","TXNID":"17527","LASTBALANCE":"-12078.8","SURCHARGE":"2","CUSTOMERDETAILS":{"NAME":"Mr.ABC"}}}
I want to retrieve value Mr.ABC when i passed Name as a key to my function
Code:
console.log(getObjects(ContextObj, 'Name'));
function getObjects(obj, key) {
var objects = [];
for (var i in obj) {
if (!obj.hasOwnProperty(i)) continue;
if (i == key) {
objects.push(obj);
}
}
return objects;
}
It gives output now as
[ ]
Try this:
var data = {"RESPONSE":{"#xmlns":"","CODE":"0","SECODE":"0","TXNID":"17527","LASTBALANCE":"-12078.8","SURCHARGE":"2","CUSTOMERDETAILS":{"NAME":"Mr.ABC"}}};
function find_value(key, inner_key) {
var value = "";
$.each(data.RESPONSE, function (i, k) {
console.log(i, key, i == key)
if (i == key) {
value = k;
return false;
}
});
if (inner_key) {
if (value[inner_key]) {
value = value[inner_key];
}
}
return value;
}
Calling function:
find_value("LASTBALANCE");
find_value("CUSTOMERDETAILS", "NAME");
See DEMO here.
You need to call your code recursive for nested json keys like,
var s={"RESPONSE":{"#xmlns":"","CODE":"0","SECODE":"0","TXNID":"17527","LASTBALANCE":"-12078.8","SURCHARGE":"2","CUSTOMERDETAILS":{"NAME":"Mr.ABC"}}};
console.log(getObjects(s, 'NAME'));
console.log(getObjects(s, 'LASTBALANCE'));
function getObjects(obj, key) {
var objects = [];
for (var i in obj) {
if(typeof obj[i] == 'object'){
return getObjects(obj[i], key); // if it is an object then find the key recursively.
}
if (!obj.hasOwnProperty(i)) continue;
if (i == key) {
return obj[key];
}
}
return '';
}
Working DEMO

Replace null values to empty values in a JSON OBJECT

Hi I've got a JSON object provided by an ajax request.
Some of the values inside the json appears as null, but I want an empty String instead
My sample of code :
$.post("/profil_process/wall/preview-post.php",param, function (data){
// this does not work
JSON.stringify(data, function(key, value) { return value === "" ? "" : value });
$('#previewWall').html(getPostWall(data.type,data.titre,data.url,data.description,data.media,data.photo_auteur,data.nom_auteur,data.url_auteur,data.date_publication)).fadeIn();
$(".bouton-vertM").show();
$("#wLoader").hide();
},'json');
Any ideas?
Your function should be like this:
function (key, value) {
return (value === null) ? "" : value;
}
If the value is null, then it returns an empty string.
If you can replace null-s with empty strings on serialized string, do something like this:
data = JSON.parse(JSON.stringify(data).replace(/\:null/gi, "\:\"\""));
Here's how you should be doing it, replacing the objects values with empty strings, not stringifying it
$.post("/profil_process/wall/preview-post.php",param, function (data){
(function removeNull(o) {
for(var key in o) {
if( null === o[key] ) o[key] = '';
if ( typeof o[key] === 'object' ) removeNull(o[key]);
}
})(data);
$('#previewWall').html(
getPostWall(
data.type,
data.titre,data.url,
data.description,
data.media,
data.photo_auteur,
data.nom_auteur,
data.url_auteur,
data.date_publication
) // ^^^ why not just pass the entire object ?
).fadeIn();
$(".bouton-vertM").show();
$("#wLoader").hide();
},'json');
For anyone still looking for a solution.
Used this in my angular 2 app to remove all null values returned by my db query.
Create an angular 2 function in the component
replacer(i, val) {
if ( val === null )
{
return ""; // change null to empty string
} else {
return val; // return unchanged
}
}
Or Javascript function
function replacer(i, val) {
if ( val === null )
{
return ""; // change null to empty string
} else {
return val; // return unchanged
}
}
Then use the function in JSON.stringify method
JSON.stringify(result, this.replacer)
I recommend you the check the return type of the Ajax because it determines how to remove null.
If it is string, you can use this:
data = data.replace(/null/g, '""'); //Stays as string
Or:
data = JSON.parse(data); // Turns to a JSON object
If it is json object, then you can use this:
data = JSON.stringify(data).replace(/null/g, '""'); //Turns to string
Here is a simple code that will convert all null values into an empty string
let myObject = {
"id":1,
"name": "Ali",
"address":null,
"phone":null,
"age":22
}
Object.keys(myObject).map(function (key, index) {
if (myObject[key] == null) {
myObject[key] = "";
}
});
console.log(myObject);
// output
/* {
"id": 1,
"name": "Ali",
"address": "",
"phone": "",
"age": 22
} */
Underscore mapObject gave me the most compact solution. Here's a complete example:
$ npm install underscore
import _, { map, each } from 'underscore';
var x = {a:null, b:1, c:'c', d:null}
var y = _.mapObject(x, function(val, key) {
return val || '';
});
console.log('No nulls:', y)
No nulls: {a:"", b:1, c:"c", d:""}
Little late to the party buy hey/ho.
The below function is the exact opposite of what you need, so just reverse engineer :D
In order to swap empty string's or strings with spaces in JSON we will need to iterate through the keys and check if a value contains an empty string.
You can complete this, easily with the .trim method. We basically check, if the length of the string trimmed, (without spaces) is equal to 0. If so we will add the same key to our new object but add a null value instead. You could also remove the length in the trim call and check if obj[keys].trim == ''.
function myFunction(obj){
const newObj = {}
for(keys in obj){
if(obj[keys].trim().length == 0){
newObj[keys] = null;
}
else{
newObj[keys] = obj[keys];
}
}
return newObj;
}
Here is the correct way to do it in JS
let data = {
"msg": "Success",
"data": [
{
"firstName": "Manish",
"lastName": "Pal",
"age": 23
},
{
"firstName": "Deepak",
"lastName": "Gupta",
"age": null
}
],
"salary": [
{
"id": "1",
"type": "SD",
"amount": 1000000
},
{
"id": "2",
"type": "C",
"ok": null
}
]
};
let mainResponse = {};
const replaceNull = (value) => {
return (value == null) ? "" : value
}
//Parse Json and check for null
const removeNullFromJson = (object1, jsonObj) => {
for (const [key, value] of Object.entries(object1)) {
if (Array.isArray(value)) {
jsonObj[key] = [];
for (let i = 0; i < value.length; i++) {
jsonObj[key].push(removeNullFromJson(value[i], {}))
}
}
else if (typeof value == "object" && value != null) {
jsonObj[key] = removeNullFromJson(value, {})
}
else {
jsonObj[key] = replaceNull(value);
}
}
return jsonObj
}
console.log(removeNullFromJson(data, mainResponse))
Hope this help
var List = [];
$.post("/profil_process/wall/preview-post.php",param, function (data){
jQuery.each(data, function (key, value) {
List.push({
ReportId : value.ReportId,
ReportType: CheckNullReturnBlank(value.ReportType),
ReportName: CheckNullReturnBlank(value.ReportName),
Description : CheckNullReturnBlank(value.Description)
})
}); },'json');
function CheckNullReturnBlank(item) {
return item = (item == null) ? '' : item;
}
You can replace null values to empty by below code in java-script
var remove_empty = function ( target ) {
Object.keys( target ).map( function ( key ) {
if ( target[ key ] instanceof Object ) {
if ( ! Object.keys( target[ key ] ).length && typeof target[ key ].getMonth !== 'function') {
target[ key ] = "";
}
else {
remove_empty( target[ key ] );
}
}
else if ( target[ key ] === null ) {
target[ key ] = "";
}
} );
return target;
};
you can read more about Object.keys
function returnblank(item){
if(item == null){
return "";
}else{
return item;
}
}

finding property in js object by name

I've got many objects that structures aren't the same. But I know that all of them have got property name 'siteName'. My question is how can I get value from this property.
Explame of few objects:
feature1 = {
display: "name",
feature: {
attributes: {
when: '111',
what: '222'
},
geometry: null
infoTemplate: undefined
},
symbol: null
siteName: 'aa'
}
feature2 = {
feature: {
attributes: {
when: '111',
what: '222'
},
geometry: null
infoTemplate: undefined
},
static: {
format: {
weight: 12,
siteName: 'cccc'
},
}
}
Here's a recursive function that should work for you.
It returns the value of the first property found with the name, otherwise returns undefined.
function findByName(obj, prop) {
for (var p in obj) {
if (p === prop) {
return obj[p];
} else if (obj[p] && typeof obj[p] === "object") {
var result = findByName(obj[p], prop);
if (result !== undefined)
return result;
}
}
}
var result = findByName(myObject, "siteName");
Or here's another variation that avoids inherited properties.
function findByName(obj, prop) {
if (obj.hasOwnProperty(prop))
return obj[prop];
for (var p in obj) {
if (obj[p] && typeof obj[p] === "object") {
var result = findByName(obj[p], prop);
if (result !== undefined)
return result;
}
}
}
Recursively loop through the objects:
function find(obj, name) {
for (var k in obj) { // Loop through all properties of the object.
if(k == name){ // If the property is the one you're looking for.
return obj[k]; // Return it.
}else if (typeof obj[k] == "object"){ // Else, if the object at [key] is a object,
var t = find(obj[k], name); // Loop through it.
if(t){ // If the recursive function did return something.
return t; // Return it to the higher recursion iteration, or to the first function call.
}
}
}
}
Usage:
find(feature1, "siteName"); //Returns "aa"
The following function should suit your needs:
function getFirstFoundPropertyValue(searchedKey, object) {
if(typeof object === "object") {
for (var key in object) {
var currentValue = object[key];
if(key === searchedKey) {
return currentValue;
}
var nested = getFirstFoundPropertyValue(searchedKey, currentValue);
if(typeof nested !== "undefined") {
return nested;
}
}
}
}
It returns the value of the key if the key is found, undefined otherwise. If the key appears several times, the first found one will be returned.

find null values in multidimensional associative array

Is there a way to search through an associative array with an unknown number of dimensions and change all the null values to an empty string?
Thanks!
Something like this maybe:
var objectNullToEmpty = function (obj) {
for (key in obj) {
if (obj[key] === null) {
obj[key] = '';
}
if (typeof obj[key] === 'object') {
objectNullToEmpty(obj[key]);
}
}
return obj;
};

Categories

Resources