localStorage and Javascript Object with arrays, save Issue - javascript

I have the follwoing Components:
patientDiseasesStorage = new Object()
patientDiseasesStorage['p158246547'] = [1, 3, 8, 2, 5] //and many more of this with different p-number
I try now to save this Object/Array Combination
localStorage.setItem('patientDiseasesStorage', JSON.stringify(patientDiseasesStorage));
But when i try to read this back from localStorage it does not have the correct values:
patientDiseasesStorage = JSON.parse(localStorage.getItem('patientDiseasesStorage'));
patientDiseasesStorage['p158246547'] is now undefined and not the array.
What am I doing wrong?

If p158246547 is a string and not a variable name, it should have quotes around it:
patientDiseasesStorage['p158246547'] = [1, 3, 8, 2, 5] //and many more of this with different p-number
Use the quotes when you pull it back out of the localStorage as well.

What browser are you using? Latest Chrome works for me.
var a = [1, 2,3]
var obj = {'a': a}
obj.a
> [1, 2, 3]
localStorage.setItem('obj', JSON.stringify(obj))
var obj2 = JSON.parse(localStorage.getItem('obj'))
obj2.a
> [1, 2, 3]

Related

How to verify JavaScript memory consumption by a piece of code

both javascript code accomplish the same task merge the second array into the first one, i have read various blogs etc claming Option 2 is more memory efficient,
Is there a way or a tool to verify and see it for myself the memory usage in the Option 2 is lower ?
Option 1
//consume a lot of memory
var array1 = [1, 2, 3];
var array2 = [4, 5, 6];
console.log(array1.concat(array2));
Option 2
//reduce the memory usage
var array1 = [1, 2, 3];
var array2 = [4, 5, 6];
console.log(array1.push.apply(array1, array2));
i tried this approach https://www.valentinog.com/blog/node-usage/ node js code, not much helpful
also tried https://github.com/paulirish/memory-stats.js dosent seems to work
Your premise is wrong. Both scripts do not accomplish the same task.
Your first option allocates a new result array with 6 elements, and leaves both array1 and array2 untouched. (See the documentation for Array.prototype.concat().)
var array1 = [1, 2, 3];
var array2 = [4, 5, 6];
console.log(array1.concat(array2)); // [1, 2, 3, 4, 5, 6]
console.log(array1); // [1, 2, 3]
console.log(array2); // [4, 5, 6]
Your second option merges the contents of array2 into array1. (See the documentation for Array.prototype.push().)
var array1 = [1, 2, 3];
var array2 = [4, 5, 6];
console.log(array1.push.apply(array1, array2)); // 6
console.log(array1); // [1, 2, 3, 4, 5, 6]
console.log(array2); // [4, 5, 6]
So the second option only requires a total of 9 array elements, while the first option requires 12. On a language level, option 2 is 25% more memory-efficient. How much memory is actually used by the JavaScript engine you're using is an implementation detail. In addition, contrived examples like these are typically not good candidates for reliable performance testing as the engine's JavaScript interpreter might apply various optimizations.

Spread syntax doesn't work to destructive an array

I am new to Javascript and is confused why the following won't work?
var array = [1, 2, 3, 4]
var spread = ...array;
I was expecting it would become 1, 2, 3, 4. Instead, it gave an error message Unexpected token .... Can anyone explain this to me?
Thank you so much!
This is the correct way, however you're not gaining anything doing that.
var array = [1, 2, 3, 4]
var spread = [...array];
console.log(spread);
If you really want to destructure that array, you need destructuring assignment:
var array = [1, 2, 3, 4]
var [one, two, three, four] = array;
console.log(one, two, three, four);
The correct way of doing what you want is:
var array = [1, 2, 3, 4]
var spread = [...array];
The syntax for using spread is:
For function calls:
myFunction(...iterableObj);
For array literals or strings:
[...iterableObj, '4', 'five', 6];
For object literals (new in ECMAScript 2018):
let objClone = { ...obj };
So, based on the syntax, for an array by using spread you are missing the square brackets []:
var array = [1, 2, 3, 4]
var spread = [...array];
console.log(spread);

Why do some operations not alter an array that was passed to a function?

Scenario 1:
var myArray = [2, 3, 4, 5];
function doStuff(arr) {
arr = [];
}
doStuff(myArray);
console.log(myArray); // [2,3,4,5]
Scenario 2:
var myArray = [2, 3, 4, 5];
function doStuff(arr) {
arr.pop();
}
doStuff(myArray);
console.log(myArray); // [2,3,4]
Why does scenario 1 not update the globally declared array but scenario 2 does?
In the first example:
You are altering the variable arr which is merely just holding a reference to the array [2, 3, 4, 5], so instead of holding a reference to [2, 3, 4, 5], it will hold a reference to another array [].
At the line var myArray = [2, 3, 4, 5];:
myArray -----------------------------------> [2, 3, 4, 5]
Then at the line doStuff(myArray);:
myArray -----------------------------------> [2, 3, 4, 5]
↑
arr ----------------------------------------------/
Then at the line arr = [];:
myArray -----------------------------------> [2, 3, 4, 5]
arr ---------------------------------------> []
=> So, after the call to doStuff, myArray is still [2, 3, 4, 5].
In the second example:
You are using the reference to [2, 3, 4, 5] stored in arr to call a function pop on it that alters it.
At the line var myArray = [2, 3, 4, 5];:
myArray -----------------------------------> [2, 3, 4, 5]
Then at the line doStuff(myArray);:
myArray -----------------------------------> [2, 3, 4, 5]
↑
arr ----------------------------------------------/
Then at the line arr.pop();:
myArray -----------------------------------> [2, 3, 4, 5].pop()
↑
arr.pop() ----------------------------------------/
Which alters the array to:
myArray -----------------------------------> [2, 3, 4]
↑
arr ----------------------------------------------/
=> So, after the call to doStuff, myArray is now [2, 3, 4].
In the first case you are doing a new memory allocation while you are actually modifying the array in the second case.
Hence in the first case the value does not get modified.
For eg:
var myArrayOne = [2, 3, 4, 5];
function doStuff(arr) {
arr = [7,8,9]; //assigining a whole new object to the copy
}
doStuff(myArrayOne);
console.log(myArrayOne); // [2,3,4,5]
// Scenario 2
var myArrayTwo = [2, 3, 4, 5];
function doStuff(arr) {
arr.pop(); //modifying the internals of the arr object
}
doStuff(myArrayTwo);
console.log(myArrayTwo); // [2,3,4]
arr is a reference to the array, which exists somewhere in memory (you don't know where, and you don't care). When you say arr = [], you're creating a new array somewhere in memory, and changing arr to refer to that new array. The old array still exists in memory. If there was nothing referring to the old array then it would eventually be garbage collected, but in this case it's still referred to by myArray so it remains untouched.
arr.pop() on the other hand is modifying the array, not changing references.
In the first function, you're just reassigning the parameter of the function. That has no effect on the passed data.
In the second, you're actually mutating the passed array via the call to pop.
Think of it this way: in
var a = 1
a = 2
Is the 1 modified in any way? No, the reference a that was pointing to it was just changed.

Lodash: Array without last element, no mutation

I'm looking for a way to retrieve my array without the last element, and without being mutated.
_.remove does mutate the array and searches by value not index (even if it was asked there)
_.without searches by value, not index
I have _.filter(array, function(el, i) { return i != array.length -1}); but siouf, not really explicit and it needs array to be stored somewhere.
Thanks
I was looking for something like "butlast", but I found initial, which does the job:
var xs = [1, 2, 3, 4];
var xs2 = _.initial(xs);
console.log(xs, xs2); // [1, 2, 3, 4] [1, 2, 3]
Array.prototype.slice might help you.
var array = [1,2,3,4,5];
var newArr = array.slice(0, -1);
console.log(array); // [1, 2, 3, 4, 5]
console.log(newArr); // [1, 2, 3, 4]
Of course you are also able to do it with lodash
Thanks
Try this:
_.take(arr, arr.length-1)

Javascript Sub-Array

I recently ran into the problem where I would like to select multiple elements from an array, to return a sub-array. For example, given the array:
a = [1, 5, 1, 6, 2, 3, 7, 8, 3]
And the index array of:
i = [3, 5, 6]
I want to select all elements in a, who's index appears in i. So the output in my simple example would be:
[6, 3, 7]
I completely realise I could use a for loop over i and construct a new array then use Array.push(a[index (in i)]) to add in each, but I was wondering if there was a clearer/cleaner way to achieve this (possibly using underscore.js, or something similar).
i.map(function(x) { return a[x]; })
// => [6, 3, 7]
You can try this
a = [1, 5, 1, 6, 2, 3, 7, 8, 3];
i = [3,5,6];
var res= []; //for show result array
for (var n in a){ //loop a[]
for(var index in i){ //loop i[]
if( n == i[index] ) //n is index of a[]
res.push(a[n]); //add array if equal n index and i[] value
}
}
alert(res); // 6,3,7
You could use map function to achieve your desired result.
var a = [1, 5, 1, 6, 2, 3, 7, 8, 3];
var i = [3, 5, 6];
var mapped = i.map(function(index) {
return a[index];
});
console.log(mapped);
Here is the working jsfiddle.
However with above example, map not be available in all browsers yet. Here is the quote from documentation of map.
map was added to the ECMA-262 standard in the 5th edition; as such it
may not be present in all implementations of the standard.
If your code will be running in old browsers then you will need to add a polyfill. However there are libraries that give you similar functionality with polyfills for older browsers. Along with map function, underscodejs has tons of other helpful functions. I higly recommend you to look at what underscorejs has to offer. It provides tons of helper functions and has quite wide range browser support.
You would do following in underscorejs and wont have to worry if your code works in cross browsers.
var a = [1, 5, 1, 6, 2, 3, 7, 8, 3];
var mapped = _.map([3, 5, 6], function(index) {
return a[index];
});
alert(mapped);
Here is jsfiddle for that.

Categories

Resources