Javascript JSON.stringify replacer return value problem? - javascript

I tried to write some javascript code that multiplies with number salaries of each person, and makes them into string with JSON.stringify.
For example, in salaries, the name and the original salary are in here like this:
let salaries = {
james:100000,
john:200000,
jane:300000
};
and I want to express like this: {james:110000,john:220000,jane:330000}
So, I wrote the code like...
let payjson = JSON.stringify(pays, function replacer(key, value){
return value*1.1;
}); // 1st try
and got an error, the values are changed like [object Object], NaN.
However, this code just worked for me
let payjson = JSON.stringify(pays, function replacer(key, value){
return Number.isInteger(value)? Math.floor(value*1.1): value;
}); // 2nd try
I wonder why the first one didn't work the way I wanted and the second just worked the way I wanted to.

As the stringify() function documentation clearly explain, the replacer function is initially passed the object, and then each of the properties. So, you are seeing this behavior. The first time when the value comes in as object type, and the multiplication is attempted, it crashes and does not subsequently pass the properties, so the overall return of the stringify() is null. In your 2nd try code, you are checking the value and only if it is of numeric type, you are doing the math and returning a calculated value, which is used by stringify() to append to the output string.
See the documentation, and mainly this paragraph :
Initially, the replacer function is called with an empty string as key representing the object being stringified. It is then called for each property on the object or array being stringified.

It looks like you want to create a copy of the original object with 10% higher salaries:
const salaries = {
james:100000,
john:200000,
jane:300000
};
const res=Object.fromEntries(Object.entries(salaries).map(([k,v])=>[k,1.1*v]));
console.log(res);
// this can be strigified too:
console.log(JSON.stringify(res));
// and the input object is unchanged:
console.log(salaries);

When the replacer function is first called, key is assigned an empty string. However, the function is still expected to return value, otherwise it terminates.
let salaries = {
james:100000,
john:200000,
jane:300000
};
document.write(JSON.stringify(salaries,(k,v)=>{return k==''?v:Math.floor(v*1.1);}));

Related

Function returns [object Set] instead of an actual Set

I have a function
function recursiveDivisionWrap(width, height, colStart, colEnd, rowStart, rowEnd)
in which i have an empty set
let blockedNodes = new Set();
inside this function I have another, recursive function
function recursiveDivision(width, height, colStart, colEnd, rowStart, rowEnd)
On each call of the recursiveDivision function i update a blockedNodes set by adding value:
for (let i = colStart; i < colEnd; i++) {
blockedNodes.add(`c${i}r${wallStart}`);
}
If I console.log blockedNodes set inside recursiveDivision function, I'm getting desired result, for example:
Set(43) {'c0r7', 'c1r7', 'c2r7', 'c3r7', 'c4r7', …}
However when I console.log blockedNodes set inside recursiveDivisionWrap and not in recursiveDivision, I'll get comma separated object:
c0r7,c1r7,c2r7,c3r7,c4r7,c5r7,c6r7,c7r7,c8r7,c9r7,c9r0,c9r1,c9r2,c9r3,c9r4,c9r5,c9r6,c8r0,c8r1,c8r2,c8r3,c8r4,c8r5,c8r6,c3r0,c3r1,c3r2,c3r3,c3r4,c3r5,c3r6,c4r6,c5r6,c6r6,c7r6,c4r1,c5r1,c6r1,c7r1,c4r5,c5r5,c6r5,c7r5
I've also tried with array and the result was the same.
Why doesn't it return Set(43) {'c0r7', 'c1r7', 'c2r7', 'c3r7', 'c4r7', …} if the blockedNodes set is defined outside the recursiveDivision function and inside recursiveDivisionWrap and why does the inner recursiveDivision function returns correct set?
I would appreciate any help in finding answer to that question.
This behaviour has nothing to do with the place where the output is made, but how the output is formatted.
You have these statements:
console.log(blockedNodes);
And:
console.log(`Is this a set? ${blockedNodes}`);
And:
let ecie = Array.from(blockedNodes);
console.log(`Is this an array? ${ecie}`)
They don't do the same thing.
console.log(blockedNodes) leaves the rendering to the console API, which may provide additional information, like the name of the constructor of the object (Set in this case), the number of items this collection has, ...etc. It may even add user-interface controls to expand/collapse the contents of the collection and potential nested data structures.
console.log(`Is this a set? ${blockedNodes}`) will implicitly call blockedNodes.toString() in order to produce the string. Unless toString has been overriden, that will render as [object Set], and so the total output will be "Is this a set? [object Set]".
console.log(`Is this an array? ${ecie}`) will also call the toString method, but this time on ecie, which is an array (as that is what Array.from returned). The toString method on arrays produces a comma separated list of the values, which explains the output you mentioned.

find value in complex object javascript

Basically I have a complex object that retrieves the GPT API (google publisher tag) with this function:
googletag.pubads().getSlots();
The object value is something like this:
I need to know if there is a way to compare the value of each property with an X value without getting a problem of recursivity (because the object is huge and i need to to that validation several times)
Also, I tried to convert that object into a JSON with JSON.stringify(), and then tried to get the value with a regex, faster, but with this option, I have the problem with Cyclic Object Value.
Any suggestions ?
it's more simple. try it to convert it into an array and later use a filter for comparative with your value.
var objGoogle = {};
var arrayObjectGoogle = [objGoogle];
var filter = arrayObjectGoogle.filter(function(obj){
obj.yourAttr == yourValue; });
this will give you a second array with the values found it. later, index the array for pick up the value do you need.

loop in JSON with undefined elements

I am trying to figure out how to retrieve the values of a json of which i do not know the number of elements.
Example:
my json can be something like
var json = ["fixelement1":"value1","fixelement2":"value2","fixelement3":"value3","variableelement4":"value4","variableelement5":"value5"]
or
var json =["fixelement1":"value1","fixelement2":"value2","fixelement3":"value3","variableelement7":"value7","variableelement8":"value8", "variableelementN":"valueN"]
the only thing that I know is that the first 3 elements are always the same.
I use .indexOf() to search a value in fixelement3. What I would like to do is, if I find the element, I would like to retrieve the name of all the following elements (which number is variable and that are unknown) and their values.
javascript or jquery would work for me, but I have no idea..
thank you in advance!
var json ={
"fixelement1":"value1",
"fixelement2":"value2",
"fixelement3":"value3",
"variableelement7":"value7",
"variableelement8":"value8",
"variableelementN":"valueN"
}
for(prop in json){
console.log('key ======> value', prop, '=====>', json[prop]);
}

Order of operations with JSON.stringify

I have the following fiddle http://jsfiddle.net/kc11/h6nh1gvw/1/ . I'm not experienced with JS.
I see that ;
alert(JSON.stringify(getCarData()[0]));
produces :
{"car":"Mercedes A 160","year":2006,"available":true,"comesInBlack":"yes"}
but:
alert(JSON.stringify(getCarData())[0]);
produces:
[
Could someone explain in plain english what is happening here? Intuitively I feel that the second operation should work in producing the first JSON record as well.
In your first line of code you provide you are serializing an object and getting the result as a JSON string. The second example it seems you were trying to treat that object as an array and serialize the first element of that array that comes back.
Assuming this is the case you need to alter the location of the parenthesis in your code to be:
alert(JSON.stringify(getCarData()[0]));
What you wrote will actually just take the first character from the JSON string returned (which is "["). Hence the output that you get from this.
One other thing that is noteworthy here though is the fact that you aren't going to get what you expect when you index an object. You probably should specify a property name that you hope to serialize, something like:
alert(JSON.stringify(getCarData()["car"]));
You get the point. Best of luck!
Lets break down what alert(JSON.stringify(getCarData())[0]); is trying to do.
Remeber PEMDAS? We are basically doing the same thing.
The deepest parenthesis call is getCarData(), which returns the array.
Next, you call JSON.stringify() on that array, which returns a string.
And finally, you call [0], which effectively grabs the first character of that string.
Assuming JSON.stringify doesn't throw an error, the result of JSON.stringify(foo) is a String, let's call this str, so
JSON.stringify(getCarData())[0];
// same as
JSON.stringify(foo)[0]; // foo = getCarData()
// same as
str[0];
So by using the [0] here you're getting the first character from a String. This will be a "[" if you've stringified an Array
Now we understand this, let's look back at JSON.stringify(foo[0]), assuming foo is Array-like.
The [0] here is selecting the item at index 0 of the array, let's call this item, so
JSON.stringify(getCarData()[0]);
// same as
JSON.stringify(foo[0]); // foo = getCarData()
// same as
JSON.stringify(item);
// so we end up with
str2; // not the same as str
This time we have stringified something from JavaScript but not done anything further, so the result is the JSON representation of whatever we called stringify on (in your case it was an Object)
getCarData() is an array of objects.
getCarData()[0] is the first object of this array of objects, so it can be stringified.
JSON.stringify(getCarData()[0]) will return a string of the the first object of the array of objects.
JSON.stringify(getCarData()) will return a string of the entire array of objects.
JSON.stringify(getCarData())[0] will return the first letter of the string produced by the above command, which is [, because you're essentially doing something like "hi"[0] which is a character, whereas previously you did {"hi","hello"}[0] which is a string element.
There is a fundamental difference between the two orders of operations, which I will explain below.
TLDR
The first call to JSON.stringify() you do gets the car data you want and then stringifies it, while the second way stringifies an array of objects containing car data and then tries to access the first element in that string, which is the first character of that string.
Let's break down what the following line is doing:
alert(JSON.stringify(getCarData()[0]));
First
getCarData()
returns and Array that has an object in it at position 0. The [0] is saying give me the first item from the array of car data returned by getCarData().
You then pass this object to the JSON.stringify() function to be stringified. This works as you expect returning:
{"car":"Mercedes A 160","year":2006,"available":true,"comesInBlack":"yes"}
The second stringify call you make:
alert(JSON.stringify(getCarData())[0]);
is getting the car data (which is returned as an array) and passing it to the JSON.stringify function.
JSON.stringify(getCarData())
This will return an array of objects containing car data. JSON then tries to stringify the array, and returns
[{"car":"Mercedes A 160","year":2006,"available":true,"comesInBlack":"yes"},{"car":"Citroen C4 Coupe","year":2008,"available":false,"comesInBlack":"yes"},{"car":"Audi A4 Avant","year":2011,"available":true,"comesInBlack":"no"},{"car":"Opel Astra","year":2004,"available":false,"comesInBlack":"yes"},{"car":"BMW 320i Coupe","year":2011,"available":false,"comesInBlack":"no"}]
Next you try to access the first item in this stringified array, but since it is now a string (not an array) it just returns [, the first character of the string.
In conclusion
The first way you do it gets the data you want and then stringifies it, while the second way stringiness an array of objects containing car data and then tries to access the first element in a string, which is the first character of that string.

Store function result to variable

How can I store the result of a function to a variable?
In navigating an object that contains an array, I am looking for one value, value1, once that is found I want to get the value of one of its properties, property1.
The code I am using below is an example and is incorrect.
function loadSets(id){
clworks.containers.find(function(i){
return i.get('property1')===id;
});
}
My intent is to navigate the object below:
clworks.containers
containers[0].property0.id
containers[1].property1.id
I am trying to determine how to find which item in the array has a property value equal to the id used in the function and then store it as a variable.
Simply:
var myVar = loadSets(id);
EDIT
Ok, as much as I understand your question now, your situation is the following:
You have an array containing objects called containers;
You want to iterate through this array, looking for the property id of the property property1 which equals the one specified in the function called loadSets(id);
Once found, store the object with the requested id in a variable.
Am I right?
If so, this should solve your problem:
// This function iterates through your array and returns the object
// with the property id of property1 matching the argument id
function loadSets( id ) {
for(i=0; i < containers.length; i++) {
if( containers[i].property1.id === id )
return containers[i];
}
return false;
}
After this you just need to do what I said in the first answer to your question, triggering it however you want. I put up a quick JSBin for you. Try to put 10, or 20, in the input field and then hitting the find button; it will return the object you are looking for. Try putting any other number, it will return a Not found.
Currently your function, loadSets, isn't actually returning anything and so you cannot store a result from it.
Try:
function loadSets(id){
return Base.containers.find(function(i){
return i.get('entityid')===id;
});
}
And to get a result into a variable:
var result = loadSets(id);

Categories

Resources