How to delete a row after matching a value in an array? - arrays

I'm using an array to handle spreadsheet data, and manipulated it. In this case, I am looking for the value of true in a column and then want to delete that row. Here's what I have:
for ( r = 1 ; r < Array1.length; r++) {
if(Array1[r][33]== true) {
calcSheet.deleteRow(Array1[r])};
}
I see the problem, but don't know the solution: firstArray[r] returns the whole row as an array, and not the row number. How can I get the row number? It's eluding me.
UPDATE: Here's the completed code. Thanks again to Serge.
You will notice that Serge pointed out a spreadsheet and array matching problem that would occur. The code below takes care of that as well; that's what all those r's are doing.
var rr = 0
for ( r = 1 ; r < firstArray.length; r++) { // iterate the first col of masterSheet
if(firstArray[r][33]== true) {
var rrr= rr + r
calcSheet.deleteRow(rrr +1);
rr--
}
}

The sheet row corresponding to this array row is r+1 if your array is really complete, ie starting on row1 (I suppose this first row is containing some headers and that's why you iterate from 1 in the array).
But there will be another side effect if you delete the row : the array will not be the exact mirror of the sheet anymore (it will be larger by 1 row each time you delete a row).
there are many ways to workaround this issue, let us know if you want some tips.

Related

How do I count the number of rows in an array?

My task is to grab a 2-dimensional table from cells on a worksheet into a 2-dimensional array, delete some or all of the rows (right terminology?) from testing, and then paste what's left into a worksheet.
To determine the range for pasting I need to know the length of the edited array. This is where I'm challenged.
// This gets the array which is 3 columns wide and X rows (X will vary)
var termEmp = spreadsheet.getRangeByName("roeList").getValues();
// e.g. termEmp = [ ["Bob", 1, "day", "key"] ["Cindy", 2, "day", "it"] ["Laura", 1, "night", "we"] ]
// Then I find the number of rows that actually have data
numRows = termEmp[0].length; // result = 3
// A for loop with counter i tests if the second element equals 2 of each row and deletes each array row if it's there
// In this example I want to delete the row with Cindy because of the 2
// To do this is use the splice method to delete the second row thusly:
termEmp.splice(i,1); // i = 1 in the for loop
// After testing all elements, and deleting the rows I want, I then need to count the number of rows remaining (to create a range for pasting into the worksheet)
numRows = termEmp[0].length;
// This is SUPPOSED to count the number of rows remaining (first element is ALWAYS non-blank)
Here's my problem. For this example the number of rows after the splice goes from 3 to 2. I looked at the array to confirm this.
But in my code termEmp[0].length STAYS at 3. I can't use it to define my range for pasting.
What's needed to get the count right?
For number of rows, you can get the length of the full array.
var numRows = termEmp.length
What you're getting with termEmp[0].length is the number of columns in first row.
EDIT
OP indicated the answer "doesn't work" (which is false) however, as a courtesy here's subsequent code that helps his followup question to identify members in an array contain another array (effectively 2-dimensional spreadsheet data). The below code will take all memembers from termEmp that are an array, and inserts them into cleanedArray.
var cleanedArray = [];
for(var i=0;i<termEmp.length;i++){
var singleMember = termEmp[i];
if(Array.isArray(singleMember)){
//makes a clean array with only 2d values
cleanedArray.push(singleMember);
}
}
var numberOfMembers = cleanedArray.length;
Logger.log(numberOfMembers);

Compare columns and rows for duplicates

Pool Reservations:
I am attempting to create a sheet for pool reservation. Column A dictates Time and Lap lane. I.e 5:15 AM 1 is for lap lane one. Column E is for the date. The time and lap lane can be scheduled for multiple days but the time/lap lane cannot be scheduled twice for the same day. I would like to highlight a row red if columns A and E within a row match A and E within a different row. In the example, both rows 3 and 6 should be highlighted red.
So right now you have three columns and you want to check if there are any duplicates in that columns.
Something like this:
I made this simple script:
function myFunction() {
const sheet = SpreadsheetApp.getActiveSheet();
const range = sheet.getRange("A1:C8");
const values = range.getValues();
for(let i = 0; i < values.length; i++){
let row = values[i];
for(let j=0; j < values.length; j++){
// Check if there are any row (excluding the current one) with the same values
if(j != i && JSON.stringify(row) === JSON.stringify(values[j])){
sheet.getRange(i+1, 1, 1, row.length).setBackground("red");
}
}
}
}
Basically I would get all the rows inside the range variable and check for every single one of them to see if there are any row repeating. I think the code itself is very self explanatory the only thing I think is worth mentioning is comparing the arrays. In javascript comparing the array would be a reference comparison, read more about it in this question.
The final result after executing the code is:

Google Script Overwriting Entire Sheet, Not Specific Range

In the function below, I grab data that is in multiple columns via a form response on my second sheet and place the information on my first sheet organized in rows.
I would like to have the first blank column after the data, currently G on my new sheet editable so that someone can come in and "approve" the contents of each row. Right now, when this script runs, it overwrites the contents of Column G. I thought the number 6 in the line with sh0.getRange(2, 1, aMain.length, 6).setValues(aMain); was telling the script to only put data into 6 columns... looks like that's not the case.
I also thought that I may be able to do a workaround by changing that line to sh0.getRange(2, 2 ... it would let me keep the first column as an editable column... that didn't work either.
Any suggestions to allow me to use this script and keep a column editable?
function SPLIT() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh0 = ss.getSheets()[0], sh1 = ss.getSheets()[1];
// get data from sheet 2
var data = sh1.getDataRange().getValues();
// create array to hold data
var aMain = new Array();
// itterate through data and add to array
// i is the loop, j=3 is the column it starts to loop with, j<9 tells it where to stop.
// in the aMain.push line, use data[i][j] for the rows to search and put in the one column.
for(var i=1, dLen=data.length; i<dLen; i++) {
for(var j=5; j<9; j++) {
aMain.push([data[i][0],data[i][1],data[i][2],data[i][3],data[i][4],data[i][j]]);
}
// add array of data to first sheet
// in the last line, change the last number to equal the number of columns in your final sheet.
// the first number in getrange is the row the data starts on... 1 is column.
sh0.getRange(2, 1, aMain.length, 6).setValues(aMain);
}
}

Modify large cell array to find certain rows that meet a condition in MATLAB

I have a cellmatrix that I want to analyse for certain rows in MATLAB. My own solution is pretty bad (see bottom), so I thought someone could give me a hint on how to improve it. I'm pretty sure, I just have to reshape the cell array somehow, but I'm not too sure how to do that.
I have one cell with logical array entries:
TheCell{with N-rows cell}(Logical Array with varying length, but max 24 entries)
For example:
TheCell{1} = [0,1,0,1,0,0,0,0,0,1,0]
TheCell{2} = [0,0,0,0]
...
TheCell{9} = [0,1,0,0,0,0,0]
Moreover, I have one matrix called Problem that tells me at which rows in "TheCell" I'm interested in (the Problem matrix has stored some certain row indexes of TheCell):
Problem(with M-rows)
For example:
Problem = [3,5,9]
I want to find all cell entries(indexes) of TheCell, where a "1" appears in either of the following positions,:
Critical = [1;2;3;4;5;6]
So for example in row Problem(3), i.e. TheCell{9} the conditions is met at Critical(2), since:
TheCell{Problem(3)}(Critical(2)) == 1
Thus I can make a new entry in my solution matrix:
Solution(counter) = Problem(3)
Finally, I have implemented this in a bad solution, not really efficient.
Critical = [1;2;3;4;5;6];
Solution = [];
counter = 1;
for i = 1:length(Problem)
Row = Problem(i);
b = length(TheCell{Row})
for k = 1:length(Critical)
if k > b
break;
end
if TheCell{Row}(Critical(k))==1
Solution(counter) = Row;
counter = counter+1;
break;
end
end
end
Critical = 6;
find(cellfun(#(x)any(x(1:min(Critical,end))), TheCell))
or if Critical won't always be consecutive numbers starting from 1 then
Critical = [2,4,5];
find(cellfun(#(x)any(x(min(Critical,end))), TheCell))
If you have control over how TheCell is created, you can probably get a far more efficient solution by not using a cell array but rather padding the ends of each row with false.
For example
TheMatrix = false(9,24);
%// You would generate this more sensibly in your process
TheMatrix(1,1:11) = [0,1,0,1,0,0,0,0,0,1,0]
TheMatrix(2,1:4) = [0,0,0,0]
...
TheMatrix(9,1:7) = [0,1,0,0,0,0,0]
Then the solution is:
find(any(TheMatrix(:,Critical),2))

Having trouble understanding multidimensional arrays in as3

Let's say I have some code like:
private function makeGrid():void
{
_grid = new Array();
for(var i:int = 0; i < stage.stageWidth / GRID_SIZE; i++)
{
_grid[i] = new Array();
for(var j:int = 0; j < stage.stageHeight / GRID_SIZE; j++)
{
_grid[i][j] = new Array();
}
}
}
I don't quite understand what's going on. I get that in the first for loop it determines the number of columns needed, and in the second it determines rows, but I don't get why I'm making arrays out of _grid[i] and _grid[i][j].
For instance, _grid[i] = new Array(); get's called 16 times (800px/50px), so that would make 16 arrays right? Why do I need those if the second for loops is already calculating the amount of rows I need?
I'm just going to elaborate on what has already been commented. Let's say that you are creating a 2D grid formed of rows and columns and you wanted to store some sort of data at each "cell" or specified index of the grid.
The first step is to create the first array to hold either the rows or columns (which you choose first doesn't really matter as you can adjust the for loops either way).
The first for loop creates a new row, then in the next inner loop you fill all the columns of that row (if we had chosen columns to be created first then we would fill all the rows of the columns). In this case the inner loop is creating all the columns with another array (making it a 3-dimensional array as mentioned in the comments).
The reason for doing this is for organization and easy look up. If you wanted to see the data stored in the 1st column of the 3rd row it would be as easy as doing _gird[2][0].
Now as to why a 3rd dimension is made as in _grid[i][j] = new Array(); that is specific to what kind of data needs to be stored at that row and column.

Resources