I have an array where I send a set of values after an operation on a spreadsheet followed by taking the average.
Now I want to return each row also along with the above data.
I thought of using two-dimensional arrays.
But I have less clarity in implementing this.
for (var i = 0; i < spreadsheetRows.length; i++)
{
//operations done and variables updated
variable1=
variable2=
variablen=
}
var sendArray = [];
sendArray.push(variable1);
sendArray.push(variable2);
sendArray.push(variable3);
sendArray.push(variable4);
return sendArray;
Now i want to send the array rowFirst & rowSecond also
for (var i = 0; i < spreadsheetRows.length; i++)
{
//first row of spreadsheet
rowFirst=[]; //data of first row
rowSecond=[]; //data of second row
//operations done and variables updated
variable1=
variable2=
variablen=
}
var sendArray = [];
sendArray.push(variable1);
sendArray.push(variable2);
sendArray.push(variable3);
sendArray.push(variable4);
sendArray.push(rowFirst); // stuck here <---
sendArray.push(rowSecond);// stuck here <----
return sendArray;
How to send the array with these two data( ie rowFirst and rowSecond) . Please guide me.
Output Expected
sendArray=[
var1,
var2,
var3,
varn,
rowFirst=[num1, num2, num3,...numn]
rowSeocnd=[num1, num2, num3,...numn]
]
To answer your immediate question, you can push an array into another array by using square brackets in push.
sendArray.push([rowFirst]);
sendArray.push([rowSecond]);
Based on your comment, you may want to use an Object, not an Array (here's a helpful article on the differences). So, think through why you'd want four variables not associated with anything. Can those be grouped or keyed somehow? There are a number of ways to do this and a simple method is to use dot notation to pair a variable or a data set to an object key.
// declare the object and each array
var sendObject = {}
// from your code...
for (var i = 0; i < spreadsheetRows.length; i++)
{
//operations done and variables updated
variable1=
variable2=
var rowFirst = [variable1, variable2, ...]
}
// Create the key in the Object and assign the array
sendObject.rowFirst = rowFirst;
The output would be:
sendObject = {
"rowFirst": [variable1, variable2, ...]
}
Related
I'm trying to push a value into a 2d array but I'm getting the error:
Cannot read property 'push' of undefined
Here's a MWE of my code:
var saida = new Array()
for (i in dbInfo){
saida[i].push(i)
}
Where dbInfo is a range in my sheet, but can be replaced by any other range for this example. I need the output to be a 2d array so I can work out the values into the sheet.
If you just created the array the array is empty. So saida[n] will be undefined no matter what value n has.
You need to first create it. Then you can push into it.
Maybe something like this? Not sure what you need.
var saida = new Array()
for (i in dbInfo){
saida[i]=[]
saida[i].push(i)
}
If dbInfo is an object of type Range from the Sheet, then the returned array after using getValues is already a 2D array so a simple assignment will suffice:
function addData() {
// your other code
let dbInfoVals = dbInfo.getValues();
let saida = dbInfoVals;
console.log(saida)
}
However, if dbInfo is a 1D array, transforming into a 2D one can be done by using the splice method in JavaScript:
function addData() {
// your other code
let saida = [];
while (dbInfo.length){
saida.push(dbInfo.splice(0, 2));
}
console.log(saida);
}
The second parameter of splice will give you the number of columns, so you might need to adjust this to match your range accordingly.
Reference
Range Class - getValues();
Array.prototype.splice().
You will need to define your array to 2d
Eg: int[,] arr= new string[3, 2];
You will need to iterate twice.
for(int col1 = 0; col1 < arr.GetLength(0); col1++){
for(int row1 = 0; row1 < arr.GetLength(1); row1++)
{
arr[col1,row1] = 2;
}
}
I am trying to pull a range of names from a Google sheet and place it into a Google Doc.In the spreadsheet, the last names("lastNames") come before the first names ("firstNames"), and both are in separate columns. I am trying to place the first and last names together into my doc with the first names first.
I used a for loop to put the first and last names together into an array ("fullNames"), and that part works just fine. When I used Logger.log, all the first names and last names are together in an array, with each full name separated by a common, just the way I wanted them to be.
What I can't figure out how to do is actually insert this new array into the body of the document. I am using the appendTable method, but every time I try to I get the following error: "The parameters (number[]) don't match the method signature for DocumentApp.Body.appendTable."
What changes do I have to make to my code to actually place my new array into my google doc?
function namePusher() {
var ss = SpreadsheetApp.openById("1CHvnejDrrb9W5txeXVMXxBoVjLpvWSi40ehZkGZYjaY");
var lastNames = ss.getSheetByName("Campbell").getRange(2, 2, 18).getValues();
var firstNames = ss.getSheetByName("Campbell").getRange(2, 3, 18).getValues();
//Logger.log(firstNames);
var fullNames = [];
for(var i = 0; i < firstNames.length; i++){
var nameConcat = firstNames[i] + " " + lastNames[i]
fullNames.push(nameConcat);
}
//Logger.log(fullNames);
var doc = DocumentApp.getActiveDocument().getBody();
doc.appendTable(fullNames);
}
Modification points:
I think that there 2 reasons in your issue.
Values retrieved by getValues() is 2 dimensional array.
data of appendTable(data) is required to be 2 dimensional array.
In your script, fullNames is 1 dimensional array. By this, such error occurs.
In your script, the values are retrieved 2 columns using 2 getValues(). In this case, the cost will become a bit high. You can retrieve the values using one getValues().
When these points are reflected to your script, it becomes as follows.
Modified script:
function namePusher() {
var ss = SpreadsheetApp.openById("1CHvnejDrrb9W5txeXVMXxBoVjLpvWSi40ehZkGZYjaY");
var values = ss.getSheetByName("Campbell").getRange("B2:C19").getValues(); // Modified
var fullNames = [];
for(var i = 0; i < values.length; i++){ // Modified
var nameConcat = [values[i][1] + " " + values[i][0]]; // Modified
fullNames.push(nameConcat);
}
var doc = DocumentApp.getActiveDocument().getBody();
doc.appendTable(fullNames);
}
References:
getValues()
appendTable(cells)
One simple way to fix your code is by replacing
fullNames.push(nameConcat);
by
fullNames.push([nameConcat]);
The problem with your script is that fullNames is an Array of strings but your should pass an Array of Arrays of strings (or objects that might be coerced to strings).
Basic demo
var data = [
['A','B','C'],
[1, 'Apple','Red'],
[2, 'Banana','Yellow']
];
function myFunction() {
const doc = DocumentApp.getActiveDocument();
const body = doc.getBody();
body.appendTable(data);
}
As mentioned on Tanaike's answer there are other "improvement opportunities"
Reduce the number of calls to the Google Apps Script Classes and Methods
Use better ways to manage Arrays and to concatenate strings.
I have an Array of Arrays populated from C# Model:
var AllObjectsArray = [];
#foreach(var Cobject in Model.ObjectList)
{
#:AllObjectsArray.push(new Array("#Cobject.Name", "#Cobject.Value", "#Cobject.Keyword"));
}
var SelectedObjects = [];
uniqueobj.forEach(function (element) {
SelectedObjects.push(new Array(AllObjectsArray.filter(elem => elem[0] === element))); //makes array of selected objects with their values(name,value,keyword)
});
I am trying to get second parameter of each and every inner Array and add it to new array containing those elements like this:
var ValuesArray = [];
for (i = 0; i < SelectedObjects.length; i++) {
ValuesArray.push(SelectedObjects[i][0]) //problem here i think
};
Unfortunately, on:
alert(ValuesArray + " : " + SelectedObjects);
I get nothing for ValuesArray. The other data for SelectedObjects loads properly with all three parameters correctly returned for each and every inner Array,so it is not empty. I must be iterating wrongly.
EDIT:
SOme more info as I am not getting understood what I need.
Lets say SelectedObjects[] contains two records like this:
{ name1, number1, keyword1}
{ name2, number2, keyword2}
Now, what I need is to populate ValuesArray with nane1 and name2.
That is why I was guessing I should iterate over SelectedObjects and get SelectedObject[i][0] where in my guessing i stands for inner array index and 1 stands for number part of that inner array. Please correct me and put me in the right direction as I am guesing from C# way of coding how to wrap my head around js.
However SelectedObject[i][0] gives me all SelectedObject with all three properties(name, value and keyword) and I should get only name's part of the inner Array.
What is happening here?
Hope I explained myself better this time.
EDIT:
I think I know why it happens, since SelectedObjects[i][0] returns whole inner Array and SelectedObjects[i][1] gives null, it must mean that SelectedObjects is not Array of Arrays but Array of strings concatenated with commas.
Is there a way to workaround this? SHould I create array of arrays ddifferently or maybe split inner object on commas and iteratee through returned strings?
First things first, SelectedObjects[i][1] should rather be SelectedObjects[i][0].
But as far as I understand you want something like
var ValuesArray = [];
for (let i = 0; i < SelectedObjects.length; i++) {
for(let j = 0; j <SelectedObjects[i].length; j++) {
ValuesArray.push(SelectedObjects[i][j]);
}
};
In this snippet
var ValuesArray = [];
for (i = 0; i < SelectedObjects.length; i++) {
ValuesArray.push(SelectedObjects[i][1]) //problem here i think
};
You're pointing directly at the second item in SelectedObjects[i]
Maybe you want the first index, 0
This function returns the same value in the array list.
For example if i=10, then my array should contain 10 different values, but it stores only the last value 10 times.
What is the problem in my code?
$scope.webTempIds=[];
$scope.wId={};
$scope.getIds=function(){
for(var i=0;i<$rootScope.retData.length;i++){
$scope.wId.ID=$rootScope.retData[i].WEBUI_TEMP_ID;
$scope.webTempIds.push($scope.wId);
}
return $scope.webTempIds;
}
$scope.wId={};
is changed every time. The array contains the reference to this object and hence when you change the value it changes the value in the array.
let obj = {};
let result = [];
for(let i = 0; i<10; i++){
obj.a = i;
result.push(obj);
}
console.log(result);
This happens because you use $scope for wId.ID outside of loop. Therefore your list items point to the same object.
Once you change $scope.wId.ID , the list $scope.webTempIds will be updated too.
To fix it make id local:
for(var i=0;i<$rootScope.retData.length;i++){
var wId = {
ID: $rootScope.retData[i].WEBUI_TEMP_ID;
}
$scope.webTempIds.push(wId);
}
As a side note: use Scope to bind application controller and the view. (inside the for loop you don't need scope)
As others have correctly pointed out, you end up with the last item in the array because the value that you push to the array is on the $scope and gets replaced with the new value each time.
To offer an alternative approach, you could use the Array.prototype.map function to return a new array prepopulated with just the id property values of each data item:
$scope.getIds=function(){
$scope.webTempIds = $rootScope.retData.map(
function(obj){
return obj.id;
}
);
}
This eliminates the need for any loops with temporary variables and any pushing to manually build up a new array from scratch.
$scope.getIds=function(){
$scope.webTempIds=[];
for(var i=0;i<$rootScope.retData.length;i++){
$scope.wId={};
$scope.wId.ID =$rootScope.retData[i].WEBUI_TEMP_ID;
$scope.webTempIds.push($scope.wId);
}
return $scope.webTempIds;
}
I have one array with data objects:
[{height: '5 feet'}, {name: 'john'}, {'hair-color': 'brown'}]
And another with the order those objects should follow in:
['name', 'height', 'hair-color']
So to sort the first array I was trying to use the sort method which compares the arrays elements two at a time and determines which should be ordered first based on a criterion, mine being the order in which each object's key appears in the second array. The problem is that the callback used by the sort method is only passed the two elements so I cannot compare them to anything in the second array because it is out of scope of the callback. Any help with this would be much appreciated, thank you.
Here's a function that will do that. I must say that your first data structure is a bit odd because there's no easy way to get the key in each object in that first array. But, I worked up a funky way to do it and it does sort:
var source = [{height: '5 feet'}, {name: 'john'}, {'hair-color': 'brown'}];
var desiredOrder = ['name', 'height', 'hair-color'];
function sortBy(src, order) {
// assumes both src and order are the same length and every item in source has a
// matching item in order and there are no empty objects in src
// this is a funky function who's job it is to find the first key in the
// object. Why the OP used a data structure like this, I have no idea!
// It makes no sense to me because it's next to impossible to use in real life
function findKey(obj) {
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
return(i);
}
}
}
// make an object that has each of the keys in it with the sort order as the value
var sortHash = {};
var i;
for (i = 0; i < order.length; i++) {
sortHash[order[i]] = i;
}
var result = new Array(src.length);
var key;
for (i = 0; i < src.length; i++) {
key = findKey(src[i]);
result[sortHash[key]] = src[i];
}
return(result);
}
var result = sortBy(source, desiredOrder);
You can see it work here: http://jsfiddle.net/jfriend00/Y8xnY/.