problem with array of object javascript ad property - javascript

I have this function that accepts an array of objects as input and transforms it into an array of strings, but when I do the console log the property are wrong, I can't understand why.
as you can see the two console logs are of the same object, in the first the x.credititoTotale property has a value in the second console.log where I go to access it directly with x.credititoTotale has another value
const stringArray = [];
export const convertToStringForDb = (objectArray) => {
objectArray.forEach((x) => {
console.log(x);
console.log(x.credititoTotale + " " + x.id);
stringArray.push(
`${x.id}/${x.cognome}/${x.nome}/${x.totaleCG}/${x.time}/${x.credititoTotale}`
);
});
return stringArray;
};
look the screen ---> screen of console.log
when I print x the value of 'credititoTotale' is '-20'
when I print x.credititoTotale the value is '-10'
it should always be the same because it is the same object printed in the same for loop

Related

ALGORITHM - File Naming

You are given an array of desired filenames in the order of their
creation. Since two files cannot have equal names, the one which comes
later will have an addition to its name in a form of (k), where k is
the smallest positive integer such that the obtained name is not used
yet.
Return an array of names that will be given to the files.
Example
For names = ["doc", "doc", "image", "doc(1)", "doc"], the output
should be fileNaming(names) = ["doc", "doc(1)", "image", "doc(1)(1)",
"doc(2)"].
One person posted this solution:
const fileNaming = names => {
const used = {};
return names.map(name => {
let newName = name;
while (used[newName]) {
newName = `${name}(${used[name]++})`;
}
used[newName] = 1;
return newName;
});
};
I'm having a hard time understanding the while block's condition.
used is an empty object.
newName is a new variable that is equal to the current item in the names array.
How does used[newName] resolve to a number? used is never set to anything other then an empty object.
This is the console output for console.log(used[newName])
Using this input:
["dd",
"dd(1)",
"dd(2)",
"dd",
"dd(1)",
"dd(1)(2)",
"dd(1)(1)",
"dd",
"dd(1)"]
In JavaScript, {} is an empty object - and as such, it can contain any number of key-value pairs. A key that is not defined has the value undefined, which evaluates to false when tested. However, any non-zero, non-NaN numerical value will evaluate to true:
console.log({}["a key that does not exist"]) // undefined
while (undefined) {
console.log("this should never be printed"); // never executes
}
while ({}["a key that does not exist"]) {
console.log("this should never be printed"); // never executes
}
if (1) {
console.log("positive numbers are true"); // writes to console
}
You can use objects as maps (even though you can also use actual maps instead in newer code)
A simpler version of the above program would have written
return names.map(name => {
let newName = name;
while (used[newName] !== undefined) { // tests for "not undefined"
newName = `${name}(${used[name]})`; // uses current value
used[name] = used[name] + 1; // sets a larger value
}
used[newName] = 1; // sets a value
return newName;
});

how to fix undefined values with functions

I'm making a program that searches through an object and prints the properties of that object to the console. The program compiles and runs, but the only thing that prints to the console is undefined. How do I fix this?
function printInfo(array) {
var usersLength = array.length;
for (var i = 0; i < usersLength; i++) {
console.log("Name: ", array.name, "Role: ", array.role);
return array.name, array.role;
}
}
This function would be passed an object with certain properties inside ( name, role, dob). The expected result is that these values would print. But what actually prints is "undefined".
Bobby
this will return undefined and an error on your console:
return array.name, array.role;
array.name property does not exist try this so you know what value function parameter has
console.log(array)
more about arrays look on this site https://www.w3schools.com/js/js_arrays.asp
If you had ES6, then use:
const printInfo = array => {
for(let info in array){
console.log(info);
}
}

Why does this really tricky computed property name function works the way it does?

#raina77ow recently helped me figure out computed property names. As part of their answer to my question, they shared a really tricky bit of code showcasing interesting aspects of JavaScript:
const increment = (() => { let x = 0; return () => ++x })();
const movingTarget = { toString: increment };
const weirdObjectLiteral = { [movingTarget]: 42 };
console.log( weirdObjectLiteral[movingTarget] ); // undefined
When I run that sample in the node CLI, that last line continually outputs undefined, while the value x in increment continually increments.
If we replace const movingTarget = { toString: increment }; with const movingTarget = { [toString]: increment };, this behaviour ceases to take place, and instead we get an output of 42 and the x in increment remains the same.
Can somebody help me understand why this is the case? What is it about JavaScript that makes things work this way?
Related Question: Does the x in the function within increment exist until we explicitly remove increment from memory?
Lets evaluate the following object literal:
{[toString]: increment }
toString is an identifier pointing to window.toString (a function) As outlined by the answer, toString will be called on that as object keys are always strings:
{[toString.toString()]: increment }
Now that results in something like:
{["function() { [native code] }"]: increment }
Now if we call toString() on this object, the standard Object.prototype.toString will get called in the {[movingTarget]: 42} part and the result is [Object object] (as always):
let x = 0;
let movingTarget = { ["function() { [native code] }"]: () => ++x };
console.log(
movingTarget.toString(), // [Object object]
{[movingTarget]: 42} // {["[Object object]"]: 42}
);
thats why the moving target isnt moving anymore. In the original code, toString of the object was set, and that gets called whenever movingTarget gets turned into a string:
let x = 0;
let movingTarget = { toString: () => ++x };
console.log(
movingTarget.toString(), // 1
"" + movingTarget, // 2
{[movingTarget]: 42} // { 3: 42 }
);
Let's dilute the complication a little bit by slightely changing the example. The following example is basically the same thing as toString is called every time movingTarget is evaluated, so we'll just get rid of it and call the function ourselves:
let x = 0;
let func = () => ++x;
const weirdObjectLiteral = { [func()]: 42 }; // equivalent to weirdObjectLiteral = { "1": 42 }
console.log( weirdObjectLiteral[func()] ); // equivalent to weirdObjectLiteral["2"]
See? The first time we called func, the value it returned was 1, so the "computed" property is "1". In the second time we called func, the returned value was 2, we tried accessing that and got undefined back because there is no property "2".
How is this related to the example in the question?
It is related because in the original code we are using movingTarget as both the value of the computed property and the key to access that property. Since both of them are expecting strings, movingTarget is coerced into a string by calling its toString method. This toString method is defined as a function that increment x and returns its new value (i.e. the inner function returned by the IIFE, the function () => ++x). So basically whenever we used movingTarget as either a computed property value or a key, that function is called and its return value was used.

Creating a JS Set inside an Array prototype

Disclaimer:
This is for learning purposes, and I already know adding methods to js built-in objects is not a good practice.
I'm trying to add a new method to the array prototype for a small hobby project:
Array.prototype.add = function (element) {
console.log('array before: ' + JSON.stringify(this));
let arr = this;
if (arr.length) {
let set = new Set(arr);
console.log('set before: ' + JSON.stringify(set));
console.log('adding element: ' + JSON.stringify(element));
set = set.add(element);
console.log('set after: ' + JSON.stringify(set));
} else {
arr.push(element);
}
console.log('array after: ' + JSON.stringify(arr));
};
On attempting to call the new method once it pushes as expected. On a consecutive call the "array before:" log prints as expected with the first push making up the contents of the array, but feeding the array to my Set constructor results in an empty set, as evidenced by my "set before:" and "set after:" logs both printing an empty {}. I'm unsure why the Set won't instantiate from the array, any help would be appreciated.
JSON.stringify always results in an empty object for sets
var s = new Set([1,2,3]);
console.log(s.size);
console.log(JSON.stringify(s));
Sets don't have properties that can be serialized. In other words, you are using the wrong method to verify whether the set is empty and are jumping to the wrong conclusion. Log set.size instead, or just set itself.
Related: JSON stringify a Set

using array.shift() affects wrong variable

I'm assuming I'm doing something really dumb here. I basically have an array that I'm passing into a function. I want to remove an element of that array and do a bunch of stuff to it, and then iterate through the rest of the array as long as there are still members in that array. When the array is empty, I want to loop back and run through the original array again.
However, I'm running into a weird issue when using array.shift(). It seems to be affecting the wrong variable if that even makes sense.
Abstract example as follows:
var originalArray = [1,2,3,4,5,6,7,8,9]
function goThroughArray(array){
var untouchedArray = array
console.log('untouched array before is ' + untouchedArray)
var insideArray = untouchedArray
console.log('inside array is ' + insideArray)
var removedNumber = insideArray.shift()
console.log('removed number: ' + removedNumber + ' from insideArray')
console.log('inside array after is ' + insideArray)
console.log('untouched array after is ' + untouchedArray)
}
goThroughArray(originalArray)
The console log output yields:
untouched array before is 1,2,3,4,5,6,7,8,9
inside array is 1,2,3,4,5,6,7,8,9
removed number: 1 from insideArray
inside array after is 2,3,4,5,6,7,8,9
untouched array after is 2,3,4,5,6,7,8,9
This is without any looping going on. Can someone explain why doing the shift() on the insideArray ALSO affects the untouchedArray??
I would expect that the insideArray would lose it's first member which is stored as "removedNumber" but why is the untouchedArray also losing it's first member?
EDIT
function addOne(number){
console.log('number in is: '+number)
var original = number;
var modified = original
console.log('original before is ' + original)
console.log('modified before is ' + modified)
modified++
console.log('original after is ' + original)
console.log('modified after is ' + modified)
}
addOne(1)
Yields:
number in is: 1
original before is 1
modified before is 1
original after is 1
modified after is 2
NEW EDIT
Although this question is super old, I figured I would update with a much cleaner method to solve this question:
JSON.parse(JSON.stringify(obj))
will create a copy of the object.
In Javascript objects are never copied. If you write
var a = [1, 2, 3, 4];
var b = a;
both a and b are just pointers to the same array object. Thus for example executing a.push(99) you will see the new element when dumping b too.
It seems that copies are done with immutable types like numbers or strings:
var a = 14;
var b = a;
b = b + 3;
console.log(a); // still 14
but this happens because the + operator returns a new number object and b is bound to this new one instead of the old one.
If you need to make a copy you must do that explicitly. For arrays the solution is calling the slice method passing no parameters.
var b = a.slice(); // Makes a new independent copy of the array
In JS, assignments are done by value:
var a = 1,
b = a; // 1 (by value)
a = 2;
b; // 1 (not modified)
However, in the case of objects, that value is a reference in memory. That means that if you modify a property of the object, you will see the change in all variables:
var obj1 = {},
obj2 = obj1;
obj1.foo = 'bar';
obj2.foo; // 'bar' (the change is reflected in the other variable)
obj1 = {}; // However, if you replace the entire object, the change
// won't be reflected because assignments are done by value
obj1.foo; // undefined
obj2.foo; // 'bar'
javascript is pass by value language. read this link for more inforamtion or google it.
In this case, you should clone your array.
try this
let insideArray = untouchedArray.slice();

Categories