Javascript - searching values in Table - javascript

I'm pretty now to programming, learning javascript at the moment. I have table, which has 754 values looking as this 000089/04/18/0601AX. I want to write script, which will return another table with values contain /04/18. Can you please help me with it?

Suppose your table is named myTable, and you can extract from it every item containing /04/18, like 000089/04/18/0601AX or 000104/04/18/0801DA and so
but not 000089/04/17/0601AX or 000089/03/18/0601AX
The script would be:
function lookFor(myval, list){
var values = []
var key
//iterate the table named list
for ( key in list)
{
//check if value myval is included in actual item of the list
if (list[key].includes(myval)){
//if so push it in the new table
values.push(list[key])
}
}
//return the new table with looking value
return values
}
var newTable
newTable =lookFor('/04/18', myTable);
all // lines ar comments you can erase them
lookFor(arg1, arg2) is a function with two arguments
arg1 is the value you want to check if is contained in a list
arg2 is the list in which you want to look
So with this function you can look for any value in a table

Related

Why won't append row work with array?

I am trying to insert a row to the bottom of a sheet, but instead of my values I see text similar to what happens when you try to print an array in Java. I checked to see if the array is made correctly with logger and it has the values I want.
var name = e.range.getRow() + SpreadsheetApp.getActiveSpreadsheet().getName();
var array = e.range.getValues().concat(name);
Logger.log(array.toString());
masterSheet.appendRow(array);
array contains a timestamp, string1, string2, and finally the name I concatenated. Instead I get something like [Ljava.lang.Object;#7dch7145
This is because appendRow() is looking for array[] not array[][].
If you attempt to append:
var array = [[1,2,3],"some string"]
It will show up as the following as it is trying to get the entire contents of the first position of the array in a single cell. It does this by returning a string of the array object which turns out to be the native code identifier.
[Ljava.lang.Object;#32dba1e2 | some string
You can append the contents of array by appending its individual members such as
ss.appendRow(array[0])
Would append
1 | 2 | 3
It looks like a problem with your use of getValues() which returns a two-dimensional array and needs to be accessed as such.
GAS API Reference: getValues()
Return
Object[][] — a two-dimensional array of values
I believe this edit to setting your var array should do the trick, assuming your data range is for a single row (index 0 will be the first row, otherwise just change the index to the row you want):
var array = e.range.getValues()[0].concat(name);

JavaScript - Retrieve variable value generated inside the for loop, externally

Well, I am working with a rest API that fetch information from the same database, but two different tables:
Table #1 contains(Outputs JSON results that contains the below objects):
id
name
type
Table #2 contains(Outputs JSON results that contains the below objects):
id
value (real-time, updated periodically)
What I want to do is to compare the id in Table #1 and compare it to id
in Table #2 and if there is a match between the two id's outputs the sum of (value) from Table #2 with all the values having the same id.
Until now what I am able to do is the following:
File1.js
require('File2.js');
for (a in metricsData){
var metricsID = metricsData[a].id;
}
/* Certainly the below code is not working, but I don't know if it should
be done this way or it can be much more better.
Can't get the values of both metricsID & idFromLoad
if(metricsID === idFromLoad) {
var sum += value;
console.log('The new sum is : '+sum)
} */
File2.js
for(var i in load.updates){
var idFromLoad = load.updates[i].id;
var newVal = load.updates[i].value;
}
So, the big question is how to get the values of both metricsID & idFromLoad outside of the for loop? Is there a better way to achieve what I am trying to do?
What you are trying to accomplish is a little confusing, but to answer the question as described in the title of this post...
Because you have the variable defined inside the loop, it only exists inside the loop. If you want to "remember" the value outside of the loop, you would need to define it outside:
var metricsID;
for (a in metricsData){
metricsID = metricsData[a].id;
}
Note though, that outside the loop, it's value will equal the id of the last item in the loop.
If you are looking for an easy way to look up values in both tables, what you could do is loop through each once and create a map keyed off the id so that you can easily retrieve the value based on the id.
var updatesMap = {};
for(var i in load.updates){
var idFromLoad = load.updates[i].id;
updatesMap[idFromLoad] = load.updates[i].value;
}
Then in your other loop:
for (a in metricsData){
var metricsID = metricsData[a].id;
var updateValue = updatesMap[meticsID]; //this is the value from the other table
}

Assign value to each indexOf match

I currently have code that searches through a single Google sheet for indexOf a number, and assigns the row number of a match to an variable. Here's an example:
for(i=0;i<values.length; i++){
itemvalue = values[i][column1-1];
codevalue = values[i][column2-1];
if(itemvalue.indexOf("5019")>-1){
row = i+1; itemcode = 5019; indexes.push(i+1)
}
}
Unfortunately the sheet contains multiple rows of strings that contain "5019". So I'm looking for a way for indexOf to continue searching and assign a new variable for the row number of each match. So if "5019" was found at row 50,51, and 54, then row,row1,row2 will be assigned to each row number.
Appreciate any help on this, also please let me know if I missed providing any information.
Edit:Thanks to the link provided by daniel, I was able to get all the matching row numbers into an array. But I'm still trying to figure out how to assign a variable to each value in the array so I can get the value of the cells that reside at the rows and add them together.
I've found the solution I sought for. Here's what I did:
for(i=0;i<values.length; i++){
itemvalue = values[i][column1-1];
codevalue = values[i][column2-1];
if(itemvalue.indexOf("5019")>-1){
row = i+1; itemcode = 5019; indexes.push(i+1)
}
for(j=k=0;j<indexes.length; j++){
rownumb.push(ss.getRange(indexes[j],qtycol).getValue()); //Get value of the cells using the row numbers from the indexes array
}
for(l=0;l<rownumb.length; l++){
rowtotal += rownumb[l]; //Adds all the values together
}
}
So I made a for loop to get the value of cells in the rows that was in the indexes array, then made a new array called "rownumb" that holds the cell values. I then made another for loop to add all the values in array rownumb together and got exactly what I was looking for.

Programmatically declaring variables based on indexed array ( working with google site list page )

imagine I have an excel like grid that consists of two parts.
A column and a list.
The column is the columns and the list is the entire collection of the all of the rows.
I can get my columns list with a .length and a .length on the list gives me the number of rows.
So I have my x and my y now.
I want to create an object out of this that would work something like this:
var = ObjList {
row0 = [],
row1 = [],
row2 = [],
column = [],
};
The issue is that the list can be modified in length. The only way i see to approach this is to programmatically create variables. Like so ( psuedo code )
//Variables
var itemName
//Get Column Names
for (var j in columns) { //columns is an object/array
var cName =columns[j].getName(); //I have to get the name otherwise cName just returns as ListItem
columnList.push(cName); //Push cName to my own array so I have an array of strings
}
for (var i in listItems) { //Again working with an object array
item = listItems[i] //Creating an easier reference variable
for (var j = 0; j < columnList.length - 1;j++){ //now I have to use the length of the Column array to find out how wide our list is
itemName = item.getValueByName(columnList[j]); //turning the listitem into a string
row(i).push(itemName); //the is the programmatic variable.
}
}
The problem is I'm not sure where I would declare the variable. Is there some other way for me to loop through the List array and match each index of the listItems array to the index of the column which I am doing here with the getValueByName(columnList[j]).
******************************Edit********************************
An example was requested and I can see how this would be confusing. This is dealing with google sites specifically.
I added comments to the above code as well.
We have a grid.This grid is actually two parts. The column is an object which is why I am creating another array and putting the names into the array. The list is another object. ( LI = lineItem )
|Col1|Col2|Col3|Col4|<~~~ Column Object
|LI |LI |LI |LI |<~~~~~~~~~~~~~~~~~~~|
|LI |LI |LI |LI |<~~~~~~~~~~~~~~~~~~~| List Object
|LI |LI |LI |LI |<~~~~~~~~~~~~~~~~~~~|
WHat I want is to be able to iterate through a loop and break each row into its own array.
I have been able to do that successfully one at a time. But since I would like to have one array per row and the number of rows is dynamic ( because a user can add more rows ) I am confused as to how I would account for that.
I want the entire grid to exist as an object with row properties and column properties that are array. So row0 would be row0[LI1,LI2,LI3,LI4]
Columns[]~~>|Col1|Col2|Col3|Col4| ~~~~~~~|
row0[]~~~~~>|LI1 |LI2 |LI3 |LI4 | ~~~~~~~|
row1[]~~~~~>|LI1 |LI2 |LI3 |LI4 | ~~~~~~~|ObjList
row2[]~~~~~>|LI1 |LI2 |LI3 |LI4 | ~~~~~~~|
Again the width of the grid is
Column.length
and the number of rows can be defined by
itemList.length
So I guess the question is can I have an array of arrays?
So I could have
//Variables
var itemName;
var masterArray = [];
var midArray = [];
//Get Column Names
for (var j in columns) {
var cName =columns[j].getName();
columnList.push(cName);
}
for (var i in listItems) {
item = listItems[i]
for (var j = 0; j < columnList.length - 1;j++){
itemName = item.getValueByName(columnList[j]);
midArray.push(itemName);
if (midArray > columnLisst.length -1) {
masterArray.push(midArray);
midArray.length = 0;
}
}
}
It feels clunky and wrong though.
Yes, you can have a 2 dimensional array in JavaScript. What you have now is an object with another level which is an array, so, in terms of dimensions, there really isn't any difference. Whether it's an object with arrays, or an object with other objects, or an array with other arrays; in all situations you have that second level.
The only issue really is; do you want to be able to access values by name rather than by index? If you want to access values by name, then use an object. Have you considered having an object inside of an object?
I don't see that you are programatically declaring variables. Maybe there is a misunderstanding of the terminology.
In this situation, where there is a second level of data, it would be normal to have nested FOR loops, so even though it's more complex, I don't think it would be considered clunky or wrong.
You'll need to run the code and look at the results to figure out what will work for you. You can use Logger.log("some text: " + aVariableName); statements to print information to the LOG, then VIEW the LOG. Also, view the EXECUTION TRANSCRIPT.
You can also step through lines of code, one line at a time, line by line and view the results.
If you have a specific problem that you can't figure out, provide the error message, and what line of code is producing the error message.

JavaScript table rows - Remove, sort via array, place back in at correct positions

I'm making a basic web application for my workplace, where a PHP script retrieves thousands of rows from an sql database, and places the data in a JavaScript object for me to control on the front end.
I've managed to make all of the above, no problem.
There are a few thousand rows in the HTML table (containing the results).
The JavaScript script dynamically changes the class of the individual s, depending on what 'column' they're in.
I can retrieve all of the 's with a particular class name, no problem, and then store the innerHTML of each of the s within an array, and sort it but how can I then remove the rows they're in from the table, sort the rows relative to the s innerHTML, then place the rows back in the table?
Again, I know how to retrieve the relevant s data, sort the data whilst also sorting where the rows should be placed (using another array) - But how can I use this array, that holds the rows 'NEW' positions, and actually apply it to the table?
I want to make this all using just JavaScript - I'd rather not use JQuery. If you remove an element from its parent element - will the child element that was removed actually destroy, or could I remove all rows from the table, sort them, then just place them back in ?
Silly question! I just wasn't brave enough to attempt it.
ANSWERED BY MYSELF.
Here's the function I made:
Where table points towards the table element, className is the class of the td you wish to sort the rows by, and ascending is a boolean variable (true / false):
function sortRows(className,ascending)
{
var rows = table.getElementsByTagName('tr');
var elements = [];
// PLACE ROW ELEMENTS IN AN ARRAY, AS .getElements RETURNED ARRAYS CAN'T BE SORTED
for(r=2;r<rows.length;r+=1){elements.push(rows[r]);}
elements.sort(function(a,b){
// SORT FUNCTION
var x = a.getElementsByClassName("name")[0].innerHTML; // VALUE IN 'NAME' <td> OF ROW A
var y = b.getElementsByClassName("name")[0].innerHTML; // VALUE IN 'NAME' <td> OF ROW B
var c = a.getElementsByClassName(className)[0]; // VALUE IN className <td> OF ROW A
var d = b.getElementsByClassName(className)[0]; // VALUE IN className <td> OF ROW B
if(c){e = c.innerHTML;} // MAKE SURE VALUE EXISTS IN DYNAMIC className CLASSED <td> A
if(d){f = d.innerHTML;} // MAKE SURE VALUE EXISTS IN DYNAMIC className CLASSED <td> B
if(isNaN(e)+isNaN(f)) // CHECK IF EITHER THE FIRST OR SECOND DYNAMIC VALUES ARE TEXT - IF SO, SORT ALPHABETICALLY
{
e=e.toLowerCase();
f=f.toLowerCase();
if(ascending==1){return(([e,f].sort().reverse()[0] == e)*2-1)}else {return(([e,f].sort()[0] == e)*2-1)}; // IF SO, SORT ALPHABETICALLY ascending OR descending
}
else if(e==f) // IF VALUES ARE real VALUES, AND BOTH THE SAME, SORT BY 'NAME' <td> OF ROWS A AND B
{
return(([x,y].sort().reverse()[0] == x)*2-1);
}
else if(ascending){return e-f;}else{return f-e;} // ELSE, SORT BY VALUES IN DYNAMICALLY RETRIEVED <td> FOR A AND B
}
);
// REMOVE ELEMENTS FROM TABLE
for(e=0;e<elements.length;e+=1)
{table.removeChild(table.childNodes[2]);}
// PLACE ELEMENTS BACK IN, ORDERED
for(r=0;r<elements.length;r+=1)
{table.appendChild(elements[r]);}
}

Categories