Replace keys JSON in javascript - javascript

Let's say I have a JSON object like
var myjson = {
"com.mycompany.top.Element" : {
"com.mycompany.top.count" : 10,
"com.mycompany.top.size" : 0
....
}
};
And I want to replace the dots/periods in the keys with a colon so the JSON becomes:
var myjson = {
"com:mycompany:top:Element" : {
"com:mycompany:top:count" : 10,
"com:mycompany:top:size" : 0
....
}
};
The JSON2 from Doublos Crockford just replaces the values not keys. Wondered if anybody else hade written a regexp or parser to replace the text making up the key?

You can use this recursive function:
function rewriteProperties(obj) {
if (typeof obj !== "object") return obj;
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
obj[prop.replace(/\./g, ":")] = rewriteProperties(obj[prop]);
if (prop.indexOf(".") > -1) {
delete obj[prop];
}
}
}
return obj;
}

Related

Extract key value pairs from json object and group them - 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/

Checking existence of nested property in an object javascript

I have already reviewed some of the answers to similar questions, however, I want to ask my question differently.
Let's say we have a string like "level1.level2.level3. ..." that indicates a nested property in an object called Obj.
The point is that we may not know how many nested properties exist in this string. For instance, it may be "level1.level2" or "level1.level2.level3.level4".
Now, I want to write a function, that given the Obj and the string of properties as input, to simply tell us if such a nested property exists in the object or not (let's say true or false as output).
Update:
Thanks to #Silvinus, I found the solution with a minor modification:
private checkNestedProperty(obj, props) {
var splitted = props.split('.');
var temp = obj;
for (var index in splitted) {
if (temp[splitted[index]] === 'undefined' || !temp[splitted[index]]) return false;
temp = temp[splitted[index]];
}
return true;
}
You could use Array#every() and thisArg of it, by iterating the keys and checking if it is in the given object.
var fn = function (o, props) {
return props.split('.').every(k => k in o && (o = o[k], true));
}
console.log(fn({}, "toto.tata")); // false
console.log(fn({ toto: { tata: 17 } }, "toto.tata")); // true
console.log(fn({ toto: { tata: { tutu: 17 } } }, "toto.foo.tata")); // false
console.log(fn({ toto: { tata: false } }, "toto.tata")); // true
You can explore your Obj with this function :
var fn = function(obj, props) {
var splited = props.split('.');
var temp = obj;
for(var index in splited) {
if(typeof temp[splited[index]] === 'undefined') return false;
temp = temp[splited[index]]
}
return true
}
var result = fn({ }, "toto.tata");
console.log(result); // false
var result = fn({ toto: { tata: 17 } }, "toto.tata");
console.log(result); // true
var result = fn({ toto: { tata: { tutu: 17 } } }, "toto.foo.tata");
console.log(result); // false
This function allow to explore nested property of Obj that depends of props passed in parameter
This answer provides the basic answer to your question. But it needs to be tweaked to handle the undefined case:
function isDefined(obj, path) {
function index(obj, i) {
return obj && typeof obj === 'object' ? obj[i] : undefined;
}
return path.split(".").reduce(index, obj) !== undefined;
}
Based on the solution given by #Silvinus here is a solution if you deal with array inside nested objects (as it is often the case in results from databases queries) :
checkNested = function(obj, props) {
var splited = props.split('.');
var temp = obj;
for(var index in splited) {
var regExp = /\[([^)]+)\]/;
var matches = regExp.exec(splited[index])
if(matches) {
splited[index] = splited[index].replace(matches[0], '');
}
if(matches) {
if(matches && typeof temp[splited[index]][matches[1]] === 'undefined') return false;
temp = temp[splited[index]][matches[1]];
}
else {
if(!matches && typeof temp[splited[index]] === 'undefined') return false;
temp = temp[splited[index]]
}
}
return true
}
obj = {ok: {ao: [{},{ok: { aa: ''}}]}}
console.log(checkNested(obj, 'ok.ao[1].ok.aa')) // ==> true
console.log(checkNested(obj, 'ok.ao[0].ok.aa')) // ==> false

Convert string with dot notation to JSON

Given a string as dot notation, how would I create an object from that string (checking for already existing properties): eg
var obj = {};
stringToObj('a.b', 'value1', obj);
stringToObj('a.b.c', 'value2', obj);
would produce
{
"a": {
"b": {
"_x": "value1",
"c": {
"_x": "value2"
}
}
}
}
I've looked at this question and this one but neither seems to be sufficient for what Im doing.
Any thoughts?
For those of you who are looking for solution without the _x in the object try this code. A slight modification of the above code (which is brilliant)
stringToObj = function(path,value,obj) {
var parts = path.split("."), part;
var last = parts.pop();
while(part = parts.shift()) {
if( typeof obj[part] != "object") obj[part] = {};
obj = obj[part]; // update "pointer"
}
obj[last] = value;
}
As bonus the above code will work if you want to update parts of an existing object :)
var obj = {a:{b:3}};
stringToObj("a.b",10,obj);
console.log(obj); //result : {a:{b:10}}
You can take advantage of references:
function stringToObj(path,value,obj) {
var parts = path.split("."), part;
while(part = parts.shift()) {
if( typeof obj[part] != "object") obj[part] = {};
obj = obj[part]; // update "pointer"
}
obj["_x"] = value;
}
To expand on both #ilikeopensource and #Niet the Dark Absol answers, I needed to add the support for arrays (multiple instances of the same path) with the possibility for nested objects. My case was more of a hybrid of dot notation and json strings.
function stringToObj(path, value, obj) {
var objValue = value;
try {
objValue = JSON.parse(value);
} catch (e) { } //eat the error, must not be json so carry on... Hack to do a valid JSON check
var parts = path.split("."), part;
var last = parts.pop();
while (part = parts.shift()) {
if (typeof obj[part] != "object")
obj[part] = {};
obj = obj[part];
}
if (obj.hasOwnProperty(last) && obj[last] && obj[last].constructor === Array) {
obj[last].push(objValue);
}
else if (obj.hasOwnProperty(last) && obj[last]) {
var objArray = [];
objArray.push(obj[last])
objArray.push(objValue);
obj[last] = objArray;
}
else {
obj[last] = objValue;
}
}
Thanks guys for the help!
This may be well answered already, but I would like to share my resolution for those who still looking for a different approach.
If you would like to convert string dot notation to a string JSON, here's my approach.
function dotToJson({ notation, inclusive = true, value = null }) {
const fragments = notation.split(".").reverse();
if (!inclusive) {
fragments.pop();
}
console.log(fragments);
return fragments.reduce((json, fragment) => {
if (isNaN(fragment)) {
return `{ "${fragment}": ${json} }`
}
let fill = "";
if (Number(fragment) > 0) {
for (let i = 0; i < fragment; i++) {
fill += "null, "
}
}
return `[${fill}${json}]`;
}, JSON.stringify(value));
};
Attribute
Meaning
notation
Dot notation string
inclusive
Include the root fragment
value
Default value for leaf
You can see the results here, I tested it using Quokka.js
NOTE: Additionally to this, thiss may help to update objects because you can use spread operator with the parsed version of the JSON

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;
}
}

return key value pair from object whose key matches certain condition with javascript and underscore

var obj = {
"M_18-24":413109,
"F_18-24":366159,
"F_25-34":265007,
"U_25-34":1214,
"U_35-44":732
}
I want to return an object with key value pairs whose keys start with either "M" or "F". So the final object would look like
var obj = {
"M_18-24":413109,
"F_18-24":366159,
"F_25-34":265007
}
I've tried things like _.filter(obj, function(v,k) { return /^[MF]/.test(k) })...
this will do the trick:
function filte_obj_FM (inp)
{
var ret = {};
for ( var k in inp)
{
if ( k[0] == "M" || k[0] == "F" )
{
ret[k] = inp[k];
}
}
return ret;
}
see console output (F12 +-> see console) here: http://jsfiddle.net/vH3ym/2/
You can try
for (var prop in obj) { console.log(prop) }
It will give you the corresponding properties, then you can add your logic like
if(prop.indexOf('M'))
This should work:
var obj = {
"M_18-24":413109,
"F_18-24":366159,
"F_25-34":265007,
"U_25-34":1214,
"U_35-44":732
}
var filtered = {}
for(var key in obj) {
if(key[0] === "M" || key[0] === "F"){
filtered[key] = obj[key]
}
}
Another version this time using reduce:
// create a new underscore function that will return the properties from an object that pass a given predicate
_.mixin({ filterProperties: function(obj, predicate){
return _.reduce(obj, function(memo, value, key){
if( predicate(key) ){
memo[key] = value;
}
return memo;
}, {});
}});
// A couple of predicates that we can use when calling the new function
function isMale(key){
return key[0] == 'M';
}
function isFemale(key){
return key[0] == 'F';
}
// and finally getting the data we want:
var males = _.filterProperties( obj, isMale );
var females = _.filterProperties( obj, isFemale );
Here's my solution:
_.filter(_.keys(obj), function(key) {
return key.match(/U/);
}).forEach(function(kv) {
delete obj[kv];
});
I think all of yours are good and I voted them up. Thanks!

Categories

Resources