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
}
Related
I have working code that takes data from two non-adjacent columns in a Google Spreadsheet, looks for unique values in the first column, and if unique creates a new array with the unique value from the first column and corresponding value in the second column. The problem is, the data I am using is already somewhat long (413 rows) and will only get longer over time. It takes about 1-2 minutes for the code to run through it. I've been looking for a shorter way to do this and I've come across the filter() and map() array functions which are supposedly faster than a for loop but I can't get them implemented correctly. Any help with these or a faster method would be greatly appreciated. The code I have right now is below.
function getkhanassignments(rows) {
var assignmentsraw = [];
var temparray = [];
var previousassignment = datasheet.getRange(50,1).getValue();
for(i=0, j=0;i<rows-1;i++) {
if(datasheet.getRange(50+i,1).getValue() != previousassignment) {
previousassignment = datasheet.getRange(50+i,1).getValue();
assignmentsraw[j] = new Array(2);
assignmentsraw[j][0] = datasheet.getRange(50+i,1).getValue();
assignmentsraw[j][1] = datasheet.getRange(50+i,8).getValue();
j++;
}
}
Logger.log(assignmentsraw);
return assignmentsraw;
}
The answers I've found elsewhere involve just getting unique values from a 1d array whereas I need unique values from a 1d combine with corresponding values from another 1d array. The output should be a 2d array with unique values from the first column and their corresponding values in the second column.
Solution:
The best practice of looping through ranges in Google Apps Script is to dump the range values into a 2D array, loop through that array, and then return the output array back to Google Sheets.
This way, there would be no calls to Sheets API inside loops.
Sample Code:
function getkhanassignments(rows) {
var assignmentsraw = [];
var table1 = datasheet.getRange(50,1,rows).getValues();
var table2 = datasheet.getRange(50,8,rows).getValues();
var previousassignment = table1[0][0];
assignmentsraw.push([table1[0][0],table2[0][0]]);
for(i=0; i<rows; i++) {
if (table1[i][0] != previousassignment) {
assignmentsraw.push([table1[i][0],table2[i][0]]);
previousassignment = table1[i][0];
}
}
Logger.log(assignmentsraw);
return assignmentsraw;
}
References:
Class Range
push()
I have these checkboxes with value in them that I would like to store and pass to php.
my function suppose to check each one of them and evaluate if thy're checked or not and then push/remove them from the array:
function isChecked(){
let distributionEL = document.querySelector("[name='distribution']");
console.log(distributionEL.value);
sendingLists.forEach(function(list) {
let sendSMSArr = distributionEL.value.split(',');
if(list.checked == true){
sendSMSArr.push(list.value);
} else {
let index = sendSMSArr.indexOf(list.value);
if (index > -1) {
sendSMSArr.splice(index, 1);
}
distributionEL.value = sendSMSArr.join(',');
});
}
What happens now is that the function repeats the existing elements of the array and then adds the new value like so. let's say my array looks like this:
sendSMSarr = ['1','2']
and after if do .push to the new value '3':
sendSMSarr = ['1','2','1','2','3']
I would like to store those values without duplicates.
As for some other data in here:
isChecked() is invoked after the loading of the page and after every search. you can search for those checkboxes in a search bar. after every search the entire div is emptied (div.innerHTML = '') and then filled with the results.
then:
// call func after every search
listR.addEventListener('change', function(){
isChecked();
})
The distributionEL is an hidden input which I use to store the values I need in a string in order to pass it to php and later convert to array agian so I can loop through it.
sendinglist is all the checkboxes in my page (document.querySelector(.checkboxes))
Manage to Isolate the problem:
Each checkbox is added when checked and removed when unchecked separately but when I check a few together without unchecking the others its start to duplicate. Obviously I would like to be able to do that without unchecking
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
I missing something when trying to push to an array while preventing duplicates.
I keep figuring out code that will push every occurence of an employee to the new employees array but I cannot figure out how to only push an unique list.
My final array is a 2d array so that can be setValues() back into a column in the Google sheet.
function queryEmployees(){
var sh = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var lRow = sh.getLastRow();
var data = sh.getRange(1,1,lRow,2).getValues();
var employees = [];
for(i=0;i<data.length;i++){
if(data[i][0]==='Team member evaluated'){
if(employees.indexOf([data[i][1]])===-1){
employees.push([data[i][1]]);
}
}
}
Logger.log(employees);
Logger.log(employees.length);
SpreadsheetApp.getActiveSpreadsheet().getSheets()[1]
.getRange(1,1,employees.length,1).setValues(employees);
}
IndexOf does not work with objects in arrays without your rewriting the function or writing your own. It works fine with strings, though. So a simple fix is to create a parallel array of strings, which allows us to keep your code almost intact. Thus, add,
var employeesIndex=[];
after your
var employees=[]
change the condition on your inner "if" clause to
(employeesIndex.indexOf(data[i][1])===-1)
and within that if block add a line to update the index
employeesIndex.push(data[i][1]);
That way the index tracks duplicates for you while your employees array contains arrays like you need.
still learning some javascript here, got done other things but now the final and most important part of it.
I have two html pages - one of which uses javascript to dynamically add text-fields (and to remove them of course) (genmain.html) and the other one where the text field input should go(table.html).
So i have already created a function to retrieve the array of values.
function getElementArray(divName){
var names = document.getElementsByName("namefield");
}
The variable names is an array and it has all the values from fields.
The problem is I would like to set these values from array to the values of another div on the page. After some searching i understood that it could be done with 'id'-s but i'm not that sure and don't completely understand how.
Let's say i have a lot of div's on another page (table.html) but some of them have id="MAIN". I would like to change the value inside of the div
For example
<div id="MAIN">THIS PART I WANT TO CHANGE</div>
Javascript is not part of my school system and i've done CodeAcademy tutorials and that's the most i've got about this, I hope you guys can help with my issue.
The variable names is an array and it has all the values from fields.
function getElementArray(divName){
var names = document.getElementsByName("namefield");
}
Nope, you've only got reference to the elements here. You've not got the value yet.
You can get the values by iterating through the names Nodelist array and use names[i].value
The problem is I would like to set these values from array to the
values of another div on the page
If it's going to be in same page, then use innerHTML or textContent property of the DOM to assign the value.
document.getElementById("MAIN").textContent= names[1].value;
Just for demo purpose am using names[1] here so it will load the second input value.
Let's say i have a lot of div's on another page (table.html) but some
of them have id="MAIN". I would like to change the value inside of the
div
Once you move to another page, the javascript state will be lost. So you wont have access to names inside that page.
Either you must store the values into localStorage and retrieve in next page.
Else add the values to query string of your URL and retrive it there.
Edit: Update based on comments
Let us assume you have var names = document.getElementsByName("namefield"); so to store the values inside localStorage.
var myValues = [],
names = document.getElementsByName("namefield");
for(var i = 0; i < names.length; i++) {
myValues.push(names[i].value);
}
localStorage.myValues = JSON.stringify(myValues);
Now if your next page, Iinside window.onload event:
window.onload = function() {
var myValues = localStorage.getItem("myValues") ? JSON.parse(localStorage.getItem("myValues")) : [],
divElements = document.querySelectorAll("#MAIN");
for(var i =0; i < myValues.length; i++) {
divElements[i].textContent = myValues[i];
}
}
If you want to set or change the contents of an element, you can use the innerHTML property.
So in your case, document.getElementById("MAIN").innerHTML = "Whatever you want";
For the record, names in your example technically isn't an array, but a NodeList. See https://developer.mozilla.org/en/docs/Web/API/NodeList#Why_is_NodeList_not_an_Array.3F.