how to delete an entire element from an associative array in javascript - javascript

I am not too good in javascript.I have an associative array in which I am putting some values.Now to iterate through the array I am using a foreach loop.Inside the foreach loop, if a condition is met I want to delete the entire element and want no empty space in the array for efficiency.However I have no idea how to get the index of an array from a foreach loop.
here is my code:
for(var j = 0 ; j < i; j++){
obstacles.push({ width:35, height:35, x:initialX, y:initialY});
}
//to iterate through the array
obstacles.forEach(o => {
o.x -= 2;
context.fillRect(o.x, o.y, o.width, o.height); //create a rectangle with the elements inside the associative array
//I need to get the index and delete the entire element and afterwards the array should resize with the other elements' index updated
}

To remove elements that comply to a certain condition from an array, Array.filter comes in handy. See MDN
let arr1 = [1,2,3,4,5,6,7,8,9,10];
// [...] to stuff to arr1
arr1 = arr1.filter(val => val % 2 === 0);
console.log(arr1);

Related

How to access an inner arrays element using a for loop in javascript [duplicate]

This question already has answers here:
Get column from a two dimensional array
(11 answers)
Closed last month.
I have a function that accepts an array of arrays as an argument and i need to get access to a specific element of the inner array to push it to a locally scoped empty array, so that i can use reduce method to return a net total.
I can get access using the map method of the specific element in the inner array and push these elements to an array but i can not seem to achieve this using a standard for loop.
// here is the array and i require access to the totals
var finances = [
["Jan-2010", 884],
["Feb-2010", 655],
["Mar-2010", 1013],
["Apr-2010", 417],
["May-2010", -7503],
["Jun-2010", 857],
["Jul-2010", 3096],
["Aug-2010", 885],
["Sep-2010", -6386],
["Oct-2010", 532],
["Nov-2010", 3810],
];
function netTotal(financeArray) {
// lets create a variable here to return the net total to the function
let net;
// lets create an empty array here to store all the totals to use with reduce method
let totals = [];
// we need to loop through the array and push element to the totals array
for (let i = 0; i < financeArray.length; i++) {
let innerArrayLength = financeArray[i].length;
for (let j = 0; j < innerArrayLength; j++) {
totals.push(financeArray[i][j]);
}
}
// lets use the reduce method to return the net total
// return (net = totals.reduce((prev, next) => prev + next));
// returning the totals array to check what is pushed to this array
return totals;
}
console.log(netTotal(finances));
// output to console
Array(22) [ "Jan-2010", 884, "Feb-2010", 655, "Mar-2010", 1013, "Apr-2010", 417, "May-2010", -7503, … ]
The totals array should be a flat array with all the amounts as elements so reduce can work to total every amount instead running the above function i get 22 elements in a single array because the original array is 11 arrays within the outer array.
How can i use the for loop to get access to only the amounts and push each element to this new empty array.
Any help much appreciated..
Your nested for loops cause all elements of the arrays to be pushed. Replace them with:
for (let i = 0; i < financeArray.length; i++) {
let innerArray = financeArray[i];
let amount = innerArray[1];
totals.push(amount);
}
Setting amount = innerArray[1] ensures you only grab the amounts and not unnecessary elements.
You can use flatMap method.
totals = financeArray.flatMap(f => f[1]);
const total = totals.reduce((prev, curr) => prev + curr, 0);
MDN: flatMap()

Iterating through multiple arrays in Javascript without using indices

I'm trying to loop over multiple arrays using a single "for in" or "for each" loop.
I have three arrays namely, name, id , and available. The size of these arrays are equal.
What I need to do is that I need to iterate through each value of the above arrays and based on the index of the row and column (values of i and j, respectively), copy the value of the element to a cell in spreadsheet.
The below is the code I am using:
for (i = 1; i <= copy_range.getNumRows(); i++) {
for (j = 1; j <= copy_range.getNumColumns(); j++) {
if (j == 1) {
var name_cell = copy_range.getCell(i, j);
// I want to do this however I'm not able to do this since I already have i and j for
// row and column iteration and that another nested loop makes things complicated
name_cell.setValue(name[k]);
}
else if (j == 2) {
var id_cell = copy_range.getCell(i, j);
Logger.log(id_cell.getA1Notation());
id_cell.setValue(id[k]); //Same idea as in previous if
}
else {
var availability_cell = copy_range.getCell(i, j);
Logger.log(availability_cell.getA1Notation());
availability_cell.setValue(available[k]); //Same as if and else if loops previously.
}
}
The reason I'm not able to use indices is that I already use i and j as iterative variables to refer to row and column, and using another nested loop does not give me the intended output - it leads to unwanted iterations and execution time.
Please let me know if there is any way where I can use a "for in" or a similar loop to iterate over each item of all the three arrays.
To me it seems like you have three "column" arrays of N entries and want to write them to a range that is N rows and 3 columns (named copy_range). The best way to do this is to join these 3 arrays into the requisite 2D array that can be written directly in a single call:
const output = name.map(function (nameVal, row) {
return [nameVal, id[row], availability[row]];
});
copy_range.setValues(output);
The above uses the Array#map method to iterate the name array, and assigns the index associated with each element nameVal to be row. The corresponding element in the id and availability arrays is then accessed using row.
Array#map

Retrieve Index Number of Unique Elements

for (let i = 0; i < arrayItemsLen; i++) {
let uniqueItems = arrayItems.filter(function(item, i, arrayItems) {
return i == arrayItems.indexOf(item);
});
}
This method retrieves unique items in the arrayItems to uniqueItems array. What I want to do is also get the index numbers of each unique element and assign it to another temp array. I can't find a way to achieve that.
E.g.: arrayItems.indexOf(item) gives the index of each unique element, but then, how do I get that index to the tempArray[i], I guess I need a for loop but I really don't know where to put it.
I would use something like
var uniqueIndices = [],
uniqueValues = [];
for(var i=0; i<array.length; ++i) {
if(uniqueValues.indexOf(array[i]) >= 0) continue;
uniqueIndices.push(i);
uniqueValues.push(array[i]);
}
Basically, it iterates array checking if the current value is already in uniqueValues. If it's there, it does nothing and continues to the next iteration. Otherwise, it adds the value to uniqueValues and the key to uniqueIndices.
Using i == array.indexOf(array[i]) like in your question would also work, but it may be slower because array will be bigger than uniqueValues.

Remove and store an array item without creating garbage

I'm looking for a performant way to remove and store elements from an array. I am trying to make an object pool to reduce garbage collections calls.
Just as .pop() and .unshift() remove elements from an array and return the value of that element, I'd like to be able to remove an element at a specific index, while storing it's value in a variable, and while not creating unnecessary arrays/objects.
.splice() removes the element at a specific index just fine, and stores that value in an array. I can access that, but the function itself creates a new array, which will eventually trigger the garbage collector.
.slice() has the same issue, a new array is created.
Is there a way to pull out and store a specific indexed element without the creation of a new array?
This always removes one item at index, if you need to remove more than 1 consecutive items at a time, it would be
more efficient to implement it to take a howMany argument and remove them in a batch instead of calling
removeAt repeatedly.
function removeAt(array, index) {
// Assumes array and index are always valid values
// place validation code here if needed
var len = array.length;
// for example if index is not valid here, it will deoptimize the function
var ret = array[index];
for (var i = index + 1; i < len; ++i) {
array[i - 1] = array[i];
}
array.length = len - 1;
return ret;
}
Usage:
var a = [1,2,3,4,5]
var removed = removeAt(a, 2);
console.log(a);
// [1, 2, 4, 5]
console.log(removed);
// 3

javascript does not splice all the element of the array

http://jsfiddle.net/4wKuj/8/
var myarr=new Array("Saab","Volvo","BMW");
console.log(myarr);
for (var i=0; i<myarr.length; i++) {
myarr.splice(i,1);
}
console.log(myarr);
Note: in the real implementation I am not trying to empty the array so plz do not suggest other way of emptying an array.
Why I still see "volvo" in the console log ?
Should not it be removed either , same as other ?
Thank You
What it does :
first iteration, i=0, removes "Saab", => array is ["Volvo","BMW"]
second iteration, i=1, removes "BMW" because this is what you have at index 1
After the first splice:
i = 1
myarr = ["Volvo", "BMW"]
So it will remove "BMW". After the second splice:
i = 2
myarr = ["Volvo"]
And the loop will not continue. Better do it like this:
while (myarr.length > 1) {
myarr.splice(0, 1);
}
before loop, your array looks like
["Saab","Volvo","BMW"]
after first iteration of loop you delete first element of array, and now array looks like
["Volvo","BMW"]
during second iteration your "i" variable has '1' (one) value that corresponds to second element of array, in other words you say:
delete in ["Volvo","BMW"] array element with index '1'
If you remove an item from the array, you also need to adjust the index value, f.ex:
var myarr=new Array("Saab","Volvo","BMW");
for (var i=0; i<myarr.length; i++) {
myarr.splice(i--,1);
}
Tip: If you are using a loop remove items from an array based on it’s value, you can use other methods, f.ex Array.filter:
myarr = myarr.filter(function(val) {
return val !== 'Volvo'
});
Array.indexOf also comes to mind.

Categories

Resources