Replacing localStorage with new values - javascript

I am reading the values from localStorage as nested array and based on some conditions, I am deleting few arrays from the read array. To delete the arrays from master array, I am using the following function:
Array.prototype.diff = function(a) {
return this.filter(function(i) {return a.indexOf(i) < 0;});
};
The resultant array is smaller than the original nested array. The following is my original array from localStorage:
var arr = `"["STAR_SPORTS_2-20170924-200043-210917-00142.jpg","PerimeterBoard","Gillette",270,399,387,397,390,472,"STAR_SPORTS_2-20170924-200043-210917-00142.jpg","PerimeterBoard","Gillette",270,399,387,397,390,472,"STAR_SPORTS_2-20170924-200043-210917-00142.jpg","PerimeterBoard","Gillette",321,322,414,333,418,375]"`
//Function to drop rectangles
function dropRects() {
dragging = false;
mLocation = getCanvasCoordinates(event);
var a = Math.floor(mLocation.x);
var b = Math.floor(mLocation.y);
var clickedImg = localStorage.getItem('clickedImage');
var arr = new Array();
var getCoords = getArray();
if (typeof getCoords !== 'undefined' && getCoords.length > 0) {
var allCoords = fourthCoord(getCoords);
arr = multiDimensionalUnique(allCoords);
the example array arr given above is the result of `multiDimensionalUnique(allCoords);
var results = new Array();
//For each item in array, perform calculation to find the array that needs to be deleted and store the found array in results - This is working properly
arr.forEach(function(d) {
if (d[0] === clickedImg && d[3] < a && d[4] < b && d[5] > a && d[6] < b && d[7] > a && d[8] > b && d[9] < a && d[10] > b) {
results.push(d)
}
});
//delete the found array from master array.
var newArr;
newArr = arr.diff(results);
//Delete the empty array [] from the master array
var secArr;
secArr = newArr.filter(function(x) { return (x !== (undefined || null || ''));})
//Delete the last two elements from each array, so that it is exactly the same as array downloaded from localStorage
for (var i = 0;i < secArr.length; i++) {
secArr[i].splice(9,2);
}
secArr = JSON.stringify(secArr)
console.log(secArr);
}
localStorage.setItem('coords', secArr);
}
The console.log(secArr) prints the following result (new array):
[["STAR_SPORTS_2-20170924-200043-210917-00142.jpg","PerimeterBoard","FBB",270,406,377,396,381,469],["STAR_SPORTS_2-20170924-200043-210917-00142.jpg","PerimeterBoard","Gillette",326,321,425,332,420,375],["STAR_SPORTS_2-20170924-200043-210917-00143.jpg","PerimeterBoard","Gillette",367,323,492,330,492,378]]
I am not sure why I have an extra square bracket at the beginning and at the end of this array. (pardon me if this result is different from the example data given above, as this is from my live dashboard)
And the line localStorage.setItem('coords', secArr) resets the localStorage with the new values which looks like this:
"[["STAR_SPORTS_2-20170924-200043-210917-00142.jpg","PerimeterBoard","FBB",270,406,377,396,381,469],["STAR_SPORTS_2-20170924-200043-210917-00142.jpg","PerimeterBoard","Gillette",326,321,425,332,420,375],["STAR_SPORTS_2-20170924-200043-210917-00143.jpg","PerimeterBoard","Gillette",367,323,492,330,492,378]]"
again with preceeding and succeeding square brackets.
Since the new array is nested within another array, when I read the localStorage again, I am not able to retrieve the array. How do I post secArr variable into localStorage as my original coords variable.

I suspect your answer is due to the double quotes in the var arr declaration. Please look at the following code:
arr = ["STAR_SPORTS_2-20170924-200043-210917-00142.jpg","PerimeterBoard","Gillette",270,399,387,397,390,472,"STAR_SPORTS_2-20170924-200043-210917-00142.jpg","PerimeterBoard","Gillette",270,399,387,397,390,472,"STAR_SPORTS_2-20170924-200043-210917-00142.jpg","PerimeterBoard","Gillette",321,322,414,333,418,375];
Array.prototype.diff = function(a) {
return this.filter(function(i) {return a.indexOf(i) < 0;});
};
clickedImg = true;
var results = new Array();
//For each item in array, perform calculation to find the array that needs to be deleted and store the found array in results - This is working properly
arr.forEach(function(d) {
if (d[0] === clickedImg && d[3] < a && d[4] < b && d[5] > a && d[6] < b && d[7] > a && d[8] > b && d[9] < a && d[10] > b) {
results.push(d)
}
});
//delete the found array from master array.
var newArr;
newArr = arr.diff(results);
//Delete the empty array [] from the master array
var secArr;
secArr = newArr.filter(function(x) { return (x !== (undefined || null || ''));})
//Delete the last two elements from each array, so that it is exactly the same as array downloaded from localStorage
for (var i = 0;i < secArr.length; i++) {
secArr[i].splice(9,2);
}
secArr = JSON.stringify(secArr)
console.log(secArr);
It produces
["STAR_SPORTS_2-20170924-200043-210917-00142.jpg","PerimeterBoard","FBB",270,406,377,396,381,469],["STAR_SPORTS_2-20170924-200043-210917-00142.jpg","PerimeterBoard","Gillette",326,321,425,332,420,375],["STAR_SPORTS_2-20170924-200043-210917-00143.jpg","PerimeterBoard","Gillette",367,323,492,330,492,378] (notice no array within array).

Related

How to remove item from an array on condition using JavaScript

I have an an array which is mentioned below. I would like to remove an item from the array which has empty property value using JavaScript.
Actual array:
[
{
"href":"/client",
"methods":[]
},
{
"href":"/home",
"methods":
{
"type1":"GET",
"type2":"POST",
}
},
{
"href":"/about",
"methods":[]
},
{
"href":"/contact",
"methods":
{
"type1":"GET",
"type2":"POST",
}
}
]
Expecting result:
[
{
"href":"/home",
"methods":
{
"type1":"GET",
"type2":"POST",
}
},
{
"href":"/contact",
"methods":
{
"type1":"GET",
"type2":"POST",
}
}
]
This is the job for filter. however filter does not modify the existing array so you need to assign it to a different array/overwrite the current variable
a = a.filter(item => Object.keys(item.methods).length > 0)
Iterate over the object array and filter based on methods property length.
var obj = [...];
obj = obj.filter((val) => val.methods && val.methods.length !== 0);
In the case of methods, you can easily walk the object and then call delete on the keys with values that are empty.... or empty arrays. I expanded the answer to cover not only keys of methods where an array is empty, but all keys with what i would define as empty contents.
var l = [];
for (var i = 0; i < l.length; i++){
var keys = Object.keys(l[i]);
for ( var j = 0; j < keys.length; j++){
var value = keys[j];
// In your use case, you are only doing arrays so i coded it as such.
if (value.length == 0){
delete l[i][j];
}
}
}
If you want to expand it to cover a variety of cases such as empty string, empty arrays, empty maps, or null values you can defined a function to do that.
function isValueDeletable(value){
if (value == null) return true;
if (value == "") return true;
if (value instanceof Array && value.length == 0) return true;
if (value instanceof Map && Object.keys(value).length == 0) return true;
return false;
}
and apply that instead of the value.length == 0;
if (isValueDeletable(value)){ delete l[i][j]; }
Then l is modified to remove all keys with empty values.
enter var json = {};
var key = "giveitakeyvalue";
json[key] = null;
delete json[key];

Array filter function

Can anyone please help me out with this code? Apparently, I just figured out that one can't run a for loop within a filter function. How can I check all the items in array "a" in the filter function?
function destroyer(arr) {
// Remove all the values
var a = [];
for (var i = 1;i < arguments.length;i++){
a.push(arguments[i]);
}
return arr.filter(function(x){
for (var b = 0;b <a.length;b++) { if (x !== a[b]){return x;} }
});
}
Array filter methods take a callback function definition which is returns true or false. true will include the item in the resulting array. false will exclude it.
Here is an example of how to use .filter():
var arr = [1,2,3,4,'a','b','c','d'];
var filteredArr = arr.filter(function(item, index) {
return typeof item === 'string' && index < 6;
});
console.log(filteredArr);
You can refer to variables outside the scope of the filter function as well:
var arr1 = [2,4,6,8];
var arr2 = [5,6,7,8];
var filteredArr = arr1.filter(function(item) {
return arr2.indexOf(item) > -1;
});
console.log(filteredArr);

Push value into array of arrays in JavaScript

I have and array of arrays which looks like this:
var arr = [[1,2,3],[4,5,6],[7,8,9]];
After that I have a list of numbers and a loop
var list = [15,10,11,14,13,12]
for (i=0; i<list.length; i++) {
var val = list[i];
if (val >= 10 && val < 13) {
arr[arr.length].push(val);
}
else if (val >= 13 && val < 16) {
arr[arr.length+1].push(val);
}
}
So basically I like to have an output which will look like this:
arr = [[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15]];
With this code I'm getting an error "Cannot read property 'push' of undefined"
Also important is I can't use arr[3].push or arr[4].push because my case is more complicated and always I need to push values to new array which will appear on the over of my array. No matter how many objects I have inside.
This is happening because arr[arr.length] will always be undefined.
So you're basically doing
undefined.push(x);
// Cannot read property 'push' of undefined
"Also important is I can't use arr[3].push or arr[4].push because my case is more complicated and always I need to push values to new array which will appear on the over of my array. No matter how many objects I have inside."
This algorithm is a code smell tho and we could probably help you better if you post your actual code.
To see what I'm talking about, consider the following code
// your numbers in a random order
var xs = [7,10,2,15,4,9,14,1,8,12,5,11,3,6,13];
// sort them
xs.sort(function(a, b) { return a-b; });
// define a function that "chunks" a list into smaller parts
function chunk(xs, n) {
function iter(ys, y, xs) {
if (y.length === 0) return ys;
return next(ys.concat([y]), xs);
}
function next(ys, xs) {
return iter(ys, xs.slice(0,n), xs.slice(n));
}
return next([], xs);
}
// call our function on your sorted list
var ys = chunk(xs, 3);
console.log(JSON.stringify(ys));
//=> [[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15]]
arr[arr.length] can never return any meaningful, think about it: if you have an array of length 6, then you have indexes 0..5 to work with.
arr[6] will always return undefined because there's nothing there.
You probably need something like this:
if (val >= 10 && val < 13) {
arr[arr.length - 1].push(val);
}
else if (val >= 13 && val < 16) {
arr[arr.length].push([val]);
}
If you are looking sort the array element then your code will not work. Refer below code to sort the element and it will also solve your undefined issue.
<script>
var arr = [[1,2,3],[4,5,6],[7,8,9]];
var list = [15,10,11,14,13,12];
var arr1=[];
var arr2=[];
for (i=0; i<list.length; i++) {
var val = list[i];
if (val >= 10 && val < 13) {
arr1.push(val);
}
else if (val >= 13 && val < 16) {
arr2.push(val);
}
}
arr1.sort(function(a, b){return a-b});
arr.push(arr1);
arr2.sort(function(a, b){return a-b});
arr.push(arr2);
console.log(arr);
</script>
You need something like this:
var arr = [[1,2,3],[4,5,6],[7,8,9]];
var list = [15,10,11,14,13,12];
for (var i=0; i<list.length; i++) {
var val = list[i];
var index = Math.floor((val-1)/3);
if ( arr[index] === undefined )
arr[index] = [];
arr[index].push(val);
arr[index].sort();
}
console.log( arr );

Delete object references to selected object by it's ID

I have a node system, which stores a bunch of nodes that are connected to other nodes. The data is structured like this:
[
{"id":0,"x":1,"y":2, "linksTo":[1]},
{"id":1,"x":3,"y":4, "linksTo":[0,2,3]},
{"id":2,"x":5,"y":6, "linksTo":[1,4]},
{"id":3,"x":3,"y":10,"linksTo":[1,4]},
{"id":4,"x":5,"y":12,"linksTo":[2,3]}
]
What I'm trying to do is delete a certain node, and all references to that in the other nodes that might be "linked" to it based on its ID.
I've gotten to the point where I can get the node i need using this function:
function getNode(id, y){
var x;
if(y){ x = id; }
if(x && y){
var nodeAtPos = false;
Object.keys(paths.list).forEach(function(i){
if(paths.list[i].x == x && paths.list[i].y == y){
nodeAtPos = paths.list[i];
return false;
}
return true;
});
return nodeAtPos;
}
return paths.list[id];
}
function deleteNode(x,y){
var obj = getNode(x,y);
//need to delete obejct and delete key references in other objects that were connected to it
}
deleteNode(5,12);
The end result would look like this in my data structure:
[
{"id":0,"x":1,"y":2, "linksTo":[1]},
{"id":1,"x":3,"y":4, "linksTo":[0,2,3]},
{"id":2,"x":5,"y":6, "linksTo":[1]}, //changed
{"id":3,"x":3,"y":10,"linksTo":[1]}, //changed
]
But as you can see in my data strucutre, if I simply delete it, I still have a few nodes that linksTo to it that I need to clean up. Otherwise they will be linked to non existant nodes.
What would be the simplest way to do this?
You could iterate each object and do the following operations:
Check if the node has its link to it. If so remove it from its
linkTo.
During the iteration, keep track of the index of the node which has
its id as the node to be deleted.
Once the iteration is done, remove the node from the array.
Code:
var x = [
{"id":0,"x":1,"y":2, "linksTo":[1]},
{"id":1,"x":3,"y":4, "linksTo":[0,2,3]},
{"id":2,"x":5,"y":6, "linksTo":[1,4]},
{"id":3,"x":3,"y":10,"linksTo":[1,4]},
{"id":4,"x":5,"y":12,"linksTo":[2,3]}
];
var index = -1;
var toDel = 2;
for(var i=0;i<x.length;i++){
if(x[i]["linksTo"].indexOf(toDel) != -1){
x[i]["linksTo"].splice(x[i]["linksTo"].indexOf(toDel),1);
}
if(x[i]["id"] == toDel){index = i;}
}
if(index != -1){
x.splice(index, 1);
}
console.log(x);
There is no other way, but to update the linksTo value for the rest of elements
var deletedId = 4;
var arr = [
{"id":0,"x":1,"y":2, "linksTo":[1]},
{"id":1,"x":3,"y":4, "linksTo":[0,2,3]},
{"id":2,"x":5,"y":6, "linksTo":[1,4]},
{"id":3,"x":3,"y":10,"linksTo":[1,4]},
];
for (var i=0 ; i < arr.length ; i++ ) {
var node = arr[i];
var newRef = [];
for (var l=0 ; l < node.linksTo.length; l++) { // l is an index for links
if (node.linksTo[l] != deletedId)
newRef.push(node.linksTo[l])
}
node.linksTo = newRef; // assign new array
}

Are there such things as dynamic-dimensional arrays in JavaScript?

What I mean by dynamic-dimensional arrays is multidimensional arrays that can have various dimensions. I need to create a function that does something to elements of multidimensional arrays, regardless of their dimensions. I wrote a function that should loop through all elements of a multidimensional array, but I can't find a way to get them. Here's what I wrote:
function loopThrough (multiArray, dimensions) {
var i, indexes = new Array(dimensions.length);
// stores the current position in multiArray as index combination
for (i in indexes) indexes[i] = 0; // position is initialised with [0, 0, ... 0]
while (i >= 0) {
doStuff(multiArray[indexes[0], indexes[1], ... indexes[?]]); // this is where I got stuck
for (i = indexes.length - 1; i >= 0 && ++indexes[i] >= dimensions[i]; indexes[i--] = 0);
// creates the next index combination
}
}
I also need a way to create such arrays. Say in an object's constructor, like:
function MultiArray (dimensions) {
this.array = [];
// create multidimensional array
}
For example, if I want to create a 5x3x8 array I should be able to call MultiArray([5,3,8]); just the same as calling MultiArray([4,6]); for a 4x6 array, or MultiArray([7]); for a plain 7-lengthed array.
You can use something like this:
function MultiArray(dimensions) {
var a = [];
if (dimensions > 1) {
a.push(MultiArray(dimensions -1));
}
return a;
}
var m = MultiArray(4);
function MultiArray(dimensions) {
this.elements = [];
var leaf = dimensions.length == 1;
var dimension = dimensions.shift();
for (var i = 0; i < dimension; ++i) {
this.elements.push(leaf ? undefined : new MultiArray(dimensions));
}
}
MultiArray.prototype.get(indexes) {
var leaf = indexes.length == 1;
var index = indexes.shift();
return leaf ? this.elements[index] : this.elements[index].get(indexes);
}
MultiArray.prototype.set(indexes, value) {
var leaf = indexes.length == 1;
var index = indexes.shift();
if (leaf) {
this.elements[index] = value;
} else {
this.elements[index].set(indexes, value);
}
return this;
}
var m = new MultiArray([4, 3, 5]);
m.set([1, 2, 4], "i'm a value in a multi dimensional array");
m.get([1, 2, 4]); // should return "i'm a value in a multi dimensional array"
m.get([2, 0, 3]); // should return undefined
m.get([0, 1]); // should return an array of 5 elements

Categories

Resources