Google Apps Scripts setValues() incorrect height error - javascript

I've looked at some other questions similar to this, but I'm getting my array in a unique way and I can't figure out for the life of my how to change it to a 2D array.
//Special function for adding arrays, just use sumArray on first array with second array in parenthesis
//==========================================
Array.prototype.sumArray = function (arr) {
var sum = this.map(function (num, idx) {
return num + arr[idx];
});
return sum;
}
var array1 = [1,2,3,4];
var array2 = [5,6,7,8];
var sum = array1.sumArray(array2);
Logger.log("sum: " + sum);
//==========================================
var calc = ss.getRangeByName( "calc" );
var target = ss.getRangeByName( "target" );
var current = ss.getRangeByName( "current" );
var left = ss.getRangeByName( "left" );
var gainedEVs = calc.getValues();
var goalEVs = target.getValues();
var oldEVs = current.getValues();
var leftEVs = left.getValues();
//Make everything ints
//==========================================
for(var i = 0; i < oldEVs.length; i++) {
Logger.log(oldEVs.length);
oldEVs[i] = parseInt(oldEVs[i]);
}
for(var i = 0; i < gainedEVs.length; i++) {
gainedEVs[i] = parseInt(gainedEVs[i]);
}
for(var i = 0; i < goalEVs.length; i++) {
goalEVs[i] = parseInt(goalEVs[i]);
}
for(var i = 0; i < leftEVs.length; i++) {
leftEVs[i] = parseInt(leftEVs[i]);
}
//==========================================
var newEVs = [[oldEVs.sumArray(gainedEVs)]];
var newLeft = [[goalEVs.subArray(newEVs)]];
//Now I try to set values and I get the error
current.setValues(newEVs);
I've tried changing the setValues to setValues([newEVs]); but that doesn't work either. Any clue on how I can get my array of newEVs to be the correct height? It has the right number of values, but those values are being stored in columns, not rows. (in this case all of my ranges are 6 rows 1 col)

Since your ranges are small, you don't have to worry too much about performance, so you can convert them from rows to columns using a loop:
var column = [];
for (var i=0; i<newEVs.length; i++){
column.push([newEVs[i]]);
}
current.setValues(column);

Related

Print elements of object array in Javascript

I have this array of objects to count element frequency in another array using for loop which prints correct output.
counts = {};
counter = 0;
counter_array = [50,50,0,200]; //this is just for example, this array is filled dynamically
for (var x = 0, y = counter_array.length; x < y; x++) {
counts[counter_array[x]] = (counts[counter_array[x]] || 0) + 1;
}
console.log('FREQUENCY: ',counts); //outputs FREQUENCY: {50:2, 0:1, 200:1}
There is another array of arrays:
holder_text_array = [["a",50,0],["b",0,0]]; //example of dynamically filled array
var p = "a";
var i = 0;
while(i < holder_text_array.length){
if (holder_text_array[i][0]==p) {
var s = counts[holder_text_array[i][1]];
console.log('Element: ', holder_text_array[i][1]); //prints 50 for i = 0
console.log('frequency: ',counts[s]); //prints undefined
counter = counts[s];
}
i++;
}
The array of arrays "holder_text_array" consists of elements whose frequency I need to get in the while loop. Can someone tell me where am I wrong?
The frequency is stored in s not in counts[s]
You're logging counts[s] where var s = counts[holder_text_array[i][1]];
You've already got the element from counts in s. Just log the value of s
Apart from that the function works!
counts = {};
counter = 0;
counter_array = [50,50,0,200]; //this is just for example, this array is filled dynamically
for (var x = 0, y = counter_array.length; x < y; x++) {
counts[counter_array[x]] = (counts[counter_array[x]] || 0) + 1;
}
console.log('FREQUENCY: ',counts); //outputs FREQUENCY: {50:2, 0:1, 200:1}
holder_text_array = [["a",50,0],["b",0,0]]; //example of dynamically filled array
var p = "a";
var i = 0;
while(i < holder_text_array.length){
if (holder_text_array[i][0]==p) {
var s = counts[holder_text_array[i][1]];
console.log('Element: ', holder_text_array[i][1]); //prints 50 for i = 0
console.log('frequency: ', s); // CHANGED THIS TO JUST `s`
counter = counts[s];
}
i++;
}
You could take a recursive approach and call the count function again for (nested) arrays with the same counts object.
The result contains the counts of each element.
function getCounts(array, counts = {}) {
for (let i = 0; i < array.length; i++) {
const value = array[i];
if (Array.isArray(value)) {
getCounts(value, counts);
continue;
}
if (!counts[value]) counts[value] = 0;
counts[value]++;
}
return counts;
}
console.log(getCounts([["a", 50, 0], ["b", 0, 0]]));
I figured out the problem. Issue is in initialization.
I changed the following:
var s = counts[holder_text_array[i][1]];
counter = counts[s];
It works this way:
var s = holder_text_array[i][1];
counter = counts[s];

Combinations of specific elements in array

Let's say that I'm doing this because of my homework. I would like to develop some kind of schedule for the week to come (array of 6-7 elements - output result). But I have one problem. I need to figure it out how one element be positioned in the array and also his frequency must be exactly what user input is. Elements must be positioned at different index in the array.
I'm having that kind of input from user (just an example);
var arrayOfElements = ["el1","el2","el3"];
var el1Frequency = 3;
var el2Frequency = 2;
var el3Frequency = 1;
//output array of schedule (this is just an example)
var finaloutPutArray = ["el1","el2","el3","el1","el2","el1"];
Index of elements el1 is 0, 3 and 5, basically, I don't want elements to be repeated like this;
["el1","el1","el2","el3"...];
["el2","el1","el1","el3"];
Can you please give me some ideas on how to solve this problem.
I started like this;
var finalSchedule = [];
var totalDaysPerWeek = 6;
for(var i =0; i < totalDaysPerWeek; i++) {
...
}
This is one pattern, check my working snippet:
var arrayOfElements = ["el1","el2","el3"];
var obj = { el1: 3,
el2: 2,
el3: 1};
// First determine the max recurring of an element, this will be the number of cycles fo your loop
// Check key values
var arr = Object.keys(obj).map(function ( key ) { return obj[key]; });
// Get max value
var max = Math.max.apply( null, arr );
var finalArray = [];
// Iterate from 0 to max val
for(i = 0; i < max; i += 1){
// Iterate on array of elements
for(k = 0; k < arrayOfElements.length; k += 1) {
// If config of recurring
if( obj[arrayOfElements[k]] >= i+1 ) {
// Push into array
finalArray.push(arrayOfElements[k]);
}
}
}
console.log(finalArray);

adding numbers in I variable in for loop javascript

I am trying to develop a calculation and I need to make a for loop that when it's calculated I need to add 3 up,
the code I use is:
var fields = [fieldname140, fieldname879, fieldname886],
result = 0.00;
for(var i = 1, h=fields.length; i<h; i++)
{
if(ABS(1-fields[i])<ABS(1-result)) result = fields[i];
}
return result;
is there a possibility to do so?
function calculate() {
var fields = ['fieldname140', 'fieldname879', 'fieldname886']; var result = '';
var newFields = [];
for(var i = 0; i < fields.length; i++){
var index = fields[i];
var indexName = index.substring(0, 9);
var indexVal = parseInt(index.substring(9));
result = indexName + (indexVal + 3);
newFields.push(result);
//console.log(result);
}
//console.log(newFields);
return newFields;
}
Call this calculate function and get new fields array with increment.

Calling all possible arrays from the length of another array

What I'm working on is a menu that auto updates its entries based on an array length. It adds groups of 10 objects' properties (in this case "IDnumbers") to the menu if a new object is added to the array.
var arraysOfObject = [], obj = {"IDNumber": ""};
for(i = 0; i<42; i++){
arraysOfObject.push({"IDNumber": "Number " + i});}
Above is the array holding 42 objects with a specific property.
var array2 = [];
var leftOver = arraysOfObject.length % 10;
var groupsOfTen = (arraysOfObject.length - leftOver)/10;
for (var i = 0; i < groupsOfTen; i++) {
array2.push([]);
for (var j = i*10; j < i*10 + 10; j++)
array2[i].push(arraysOfObject[j]["IDNumber"]);
}
//now the leftover
if (leftOver > 0) {
array2.push([]);
for (var i = groupsOfTen*10; i < arraysOfObject.length; i++)
array2[array2.length-1].push(arraysOfObject[i]["IDNumber"]);
}
The array2 above is the array that stores all the possible arrays that can be grouped by 10 from arraysOfObject. In this case there are 5 inside of it, because 4 arrays holds 40 objects, and 1 array holds the 2 remainders.
That all works fine, but placing the array2 inside the menu displays all possible IDnumbers grouped together, but not grouped individually. I have to declare each possible array inside of it like so sets = [array2[0], array2[1], array2[2], array2[3], array2[4]]; If there's a 6th possible array because object #51 has been added to arraysOfObject, I have to input it with array2[5].
I don't want it to depend on my input, but that it knows the number of possible arrays and that it displays it automatically in sets. How do I do that?
var gui = new dat.GUI();
var guiData = function() {
this.message = "Dat.Gui menu";
this.system = 0;
this.Sets = 0;
};
var data = new guiData();
sets = [array2[0], array2[1], array2[2], array2[3], array2[4], array2[5]];
gui.add(data, 'message', 'Dat.Gui Menu!');
gui.add(data, 'system', {
"1": 0,
"2": 1,
"3": 2,
"4": 3,
"5": 4,
"6": 5,
}).name('system #').onChange(function(value) {
updateSets(value);
});
gui.add(data, 'Sets', sets[0]).onChange();
function updateSets(id) {
var controller = gui.__controllers[2];
controller.remove();
gui.add(data, 'Sets', sets[id]).onChange();
data.Sets = 0;
gui.__controllers[2].updateDisplay();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.1/dat.gui.min.js"></script>
<script>
var arraysOfObject = [], obj = {"IDNumber": ""};
for(i = 0; i<42; i++){
arraysOfObject.push({"IDNumber": "Number " + i});}
var array2 = [];
var leftOver = arraysOfObject.length % 10;
var groupsOfTen = (arraysOfObject.length - leftOver)/10;
for (var i = 0; i < groupsOfTen; i++) {
array2.push([]);
for (var j = i*10; j < i*10 + 10; j++)
array2[i].push(arraysOfObject[j]["IDNumber"]);
}
//now take care of the leftover
if (leftOver > 0) {
array2.push([]);
for (var i = groupsOfTen*10; i < arraysOfObject.length; i++)
array2[array2.length-1].push(arraysOfObject[i]["IDNumber"]);
}
</script>
Not the issue at hand, but I was playing around with the dat.gui as you posted it and was wondering if the dropdown could be refilled without removing/adding/etc. It seems to work with .options. (NB The initialization code makes heavy use of ES6, but can work without. The system menu is created dynamically from the sets array)
let arraysOfObject =Array.from({length:42}, (o,i) => "Number " + i),
ch =10, sets = Array.from({length:Math.ceil(arraysOfObject.length/ch)}, (a,i) => arraysOfObject.slice(i*=ch, i+ch));
var gui = new dat.GUI();
var guiData = function() {
this.message = "Dat.Gui menu";
this.system = 0;
this.Sets = 0;
};
var data = new guiData();
gui.add(data, 'message', 'Dat.Gui Menu!');
gui.add(data, 'system', sets.reduce((obj,s,i) => (obj[i+1] = i, obj), {})).name('system #').onChange(updateSets);
let controller = gui.add(data, 'Sets');
updateSets(0);
function updateSets(id) {
controller = controller.options(sets[data.Sets = id]);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.1/dat.gui.min.js"></script>
I think the easiest solution would be to use ES2015's spread operator which I don't know if you would want to use yet...
ES2015 method (demo)
sets = [...array2];
There are a few other changes in the demo to set the system variable
But after taking a closer look, you can optimize the code by using the method from this SO answer to chunk your array using slice(). Also, I'm not sure why an object was used to create array entries when it just ends up as a string... demo
var arraysOfObject = [],
system = {},
chunk = 10,
size = 92;
for (var i = 0; i < size; i++) {
arraysOfObject.push("Number " + i);
}
var sets = [];
var index = 0;
for (i = 0; i < size; i += chunk) {
sets.push(arraysOfObject.slice(i, i + chunk));
system[index + 1] = index++;
}
var gui = new dat.GUI();
var guiData = function() {
this.message = "Dat.Gui menu";
this.system = 0;
this.Sets = 0;
};
var data = new guiData();
gui.add(data, 'message', 'Dat.Gui Menu!');
gui
.add(data, 'system', system)
.name('system #')
.onChange(function(value) {
updateSets(value);
});
gui.add(data, 'Sets', sets[0]).onChange();
function updateSets(id) {
var controller = gui.__controllers[2];
controller.remove();
gui.add(data, 'Sets', sets[id]).onChange();
data.Sets = 0;
gui.__controllers[2].updateDisplay();
}

How to create an array like this in JavaScript?

I want to create an array like this:
s1 = [[[2011-12-02, 3],[2011-12-05,3],[5,13.1],[2011-12-07,2]]];
How to create it using a for loop? I have another array that contains the values as
2011-12-02,3,2011-12-05,3,2011-12-07,2
One of possible solutions:
var input = ['2011-12-02',3,'2011-12-05',3,'2011-12-07',2]
//or: var input = '2011-12-02,3,2011-12-05,3,2011-12-07,2'.split(",");
var output = [];
for(i = 0; i < input.length; i += 2) {
output.push([t[i], t[i + 1]])
}
If your values always come in pairs:
var str = '2011-12-02,3,2011-12-05,3,2011-12-07,2',//if you start with a string then you can split it into an array by the commas
arr = str.split(','),
len = arr.length,
out = [];
for (var i = 0; i < len; i+=2) {
out.push([[arr[i]], arr[(i + 1)]]);
}
The out variable is an array in the format you requested.
Here is a jsfiddle: http://jsfiddle.net/Hj6Eh/
var s1 = [];
for (x = 0, y = something.length; x < y; x++) {
var arr = [];
arr[0] = something[x].date;
arr[1] = something[x].otherVal;
s1.push(arr);
}
I've guessed here that the date and the other numerical value are properties of some other object, but that needn't be the case...
I think you want to create an array which holds a set of arrays.
var myArray = [];
for(var i=0; i<100;i++){
myArray.push([2011-12-02, 3]); // The values inside push should be dynamic as per your requirement
}

Categories