I'm pretty new to this field. So, currently, I want to make a simple feature for my website where if the user input like width and height value, the program will make an array that combines the two values but the other one is in alphabet form. So, for example, the user input weight = 4, and height = 2, I want the array to produce [A1, A2, B1, B2, C1, C2, D1, D2]. But, I got stuck in the part where combining those numbers and alphabet. As you can see from the snippet, I use for loop for most of the process. But, in the nested for loop, it will produce like [A1, A12, A1, A12] and so on. The alphabet is not changing and the number is stacking. I really need your help, Thank you!
var askW = prompt('Enter width value');
var askH = prompt('Enter height value');
mapGenerator(askW, askH);
function mapGenerator(askW, askH){
var w = Number(askW);
var h = Number(askH);
var containerW = [];
var containerH = [];
var initialCharValue = 64;
var i;
for (i = 64 ; i <= w + initialCharValue; i++){
containerW.push(String.fromCharCode(i));
}
for (i = 1 ; i <= h; i++){
containerH.push(i);
}
console.log(containerW);
console.log(containerH);
mapGenerator2(containerW, containerH);
function mapGenerator2(containerW, containerH){
var temparray = [];
var repeated = [];
var testArr = [];
var i,j,a,b,chunk = 1;
for (i=1,a=containerW.length; i<=a; i++) {
temparray[i] = containerW.slice(i,i+chunk);
repeated[i] = new Array(containerH.length).fill(temparray[i]).flat();
}
for (i=1, a = containerW.length; i<a ; i++){
testArr = repeated[i].map(function(item) {
for(i=1, a = containerW.length; i<a ; i++){
console.log(item+= i);
}
console.log(testArr);
});
}
}
}
P.S.: In the nested for loop, I use console.log because if I push the items into the array, it will like lagging and not logging console.
you need to create two loops that are nested the first loop will be in charge of the alphabet and the second will be in charge of the numbers like so:
function mapGenerator2(height, width) {
const result = [];
for(let i = 0; i < width; i++) {
for(let j = 1; j <= height; j++) {
result.push(`${String.fromCharCode(65 + i)}${j}`);
}
}
return result;
}
console.log(mapGenerator2(2, 4));
I have updated your MapGenerator Function which shows the correct way of using nested for loops
var askW = prompt('Enter width value');
var askH = prompt('Enter height value');
mapGenerator(askW, askH);
function mapGenerator(askW, askH){
var w = Number(askW);
var h = Number(askH);
var containerW = [];
var containerH = [];
var initialCharValue = 64;
var i;
for (i = 64 ; i <= w + initialCharValue; i++){
containerW.push(String.fromCharCode(i));
}
for (i = 1 ; i <= h; i++){
containerH.push(i);
}
result = mapGenerator2(containerW, containerH);
console.log(result)
function mapGenerator2(containerW, containerH){
var resultarray = [];
containerW.shift();
containerW.forEach(function(itemW) {
containerH.forEach(function(itemH) {
resultarray.push(itemW + itemH.toString());
})
});
return resultarray;
}
}
Related
I am developing some Stock tools with AppScript and now I dont know why I cannot assign the array A values to array B. Could someone help me ?
I want to copy the values_array [l][0] -> dataArray [l][0]
Could you please give me the solution please?
//Filled up the array for MACD
// var dataArray = [["Stock","Date","Close Price","EMA12","EMA26","DIF","Signal"]];
var dataArray = [];
var accumulationEMA12 = 0;
for (var l = 0; l < values_array.length - 1; l++) // Get the previous day EMA12
{
var temp = values_array[l][5];
// var accumulationEMA12 = accumulationEMA12 + values_array[l][5];
var accumulationEMA12 = accumulationEMA12 + temp;
dataArray[l][0] = values_array[l][0]; // Fill Up the Stock No. <-Here
dataArray[l][1] = values_array[l][1]; // Fill UP the Date <-Here
if (l < 11) //if the dataset is < 12 rows or < 26 rows, calculate the average instead of EMA
{
}
}
//Filled up the array for MACD
// var dataArray = [["Stock","Date","Close Price","EMA12","EMA26","DIF","Signal"]];
var dataArray = [];
var accumulationEMA12 = 0;
for(var l = 0; l< values_array.length-1; l++) // Get the previous day EMA12
{
var temp = values_array[l][5];
// var accumulationEMA12 = accumulationEMA12 + values_array[l][5];
var accumulationEMA12 = accumulationEMA12 + temp;
dataArray[l][0] = values_array[l][0]; // Fill Up the Stock No.
dataArray[l][1] = values_array[l][1]; // Fill UP the Date
if(l < 11) //if the dataset is < 12 rows or < 26 rows, calculate the average instead of EMA
{
}
}
Values_array here
I think you are getting error at the line
dataArray[l][0] = values_array[l][0];
Because, no where I see you have initiated dataArray[l]. In your code, dataArray[l] is undefined, so when you try to do something like dataArray[l][1], you are essentially doing undefined[1] which will throw such type error
Uncaught TypeError: Cannot read property '1' of undefined
So what you need to do is, make sure dataArray[l] is an array itself. Something like this
var dataArray = [];
for (var l = 0; l < values_array.length; l++) {
// make sure dataArray[l] exists
dataArray[l] = [];
// do your operations
dataArray[l][0] = values_array[l][0];
dataArray[l][1] = values_array[l][1];
// other code.
}
Although, I would suggest using modern JS language features, like
const dataArray = [];
values_array.forEach((val, index)=> {
// notice that we are assigning a new array to dataArray[index]
dataArray[index] = [
val[0],
val[1],
];
// do other operations like
if (index < 11) {
// do stuff
}
});
Hope it helps.
I'm working from the solution provided HERE to compare two arrays. The example provided returns values found in both arrays to Array1 (same) and values only found on one or the other two Array2 (diff).
ISSUE: When I apply it to my own script, valuesDATA returns nothing and valuesCheckSeeding returns ALL values from both arrays
DESIRED RESULT: I have two arrays that I'd either like to create a third out of, or only select values from the first array, valuesDATA which are NOT present in the second, valuesCheckSeeding. Using the solution above, I was trying to have all values not found in valuesCheckSeeding AND valuesDATA pushed to valuesDATA.
SAMPLE OF valuesDATA: "U09 F
Harford FC Hill/Healey - A
MD
CMSA Girls Saturday U09 A/B North
Premier - Top
TID0118"
What am I doing wrong? I tinkered with changing matchfound==false and matchfound=true in the loop, but that still didn't give me the desired result.
MOST RELEVANT SNIPPET
var matchfound = false;
for (var i = 0; i < valuesDATA.length; i++) {
matchfound=false;
for (var j = 0; j < valuesCheckSeeding.length; j++) {
if (valuesDATA[i] == valuesCheckSeeding[j]) {
valuesCheckSeeding.splice(j, 1);
matchfound=true;
continue;
}
}
if (matchfound==false) {
valuesCheckSeeding.push(valuesDATA[i]);
valuesDATA.splice(i, 1);
i=i-1;
}
}
WORKIG SCRIPT EDITED FROM COMMENTS/ANSWERS BELOW
//UPDATE SEEDING SHEET
function updateSeedingSheet() {
var today = Utilities.formatDate(new Date(),Session.getScriptTimeZone(), "MM/dd/yyyy hh:mm a");
//INPUT SHEET INFO
var inputCurrentRow = 4;
var inputCurrentColumn = 20;
var inputNumRows = 1000;
var inputNumColumns =1;
var ssInput = SpreadsheetApp.openById('1Wzg2BklQb6sOZzeC0OEvQ7s7gIQ07sXygEtC0CSGOh4');
var sheetDATA = ssInput.getSheetByName('DATAREF');
var rangeDATA = sheetDATA.getRange(inputCurrentRow, inputCurrentColumn, inputNumRows, inputNumColumns);
var valuesDATA = rangeDATA.getValues();
//SEEDING SHEET INFO
var seedingCurrentRow = 4;
var seedingCurrentColumn = 1;
var seedingNumRows = 1000;
var seedingNumColumns = 1;
var ssSeeding = SpreadsheetApp.openById('1DuCHeZ3zba-nHq-7vYTrylncPGqcA1J9jNyW9DaS3mU');
var sheetSeeding = ssSeeding.getSheetByName('Seeding');
var rangeCheckSeeding = sheetSeeding.getRange(4, 102, 1000, 1);
var columnToClear = sheetSeeding.getRange(seedingCurrentRow, seedingCurrentColumn, seedingNumRows, seedingNumColumns);
var valuesCheckSeeding = rangeCheckSeeding.getValues();
//METHOD TO FILTER
valuesCheckSeeding = valuesCheckSeeding.map(function(e){return e[0];}); //flatten this array
var filteredArr = valuesDATA.filter(function(e){
return !(this.indexOf(e[0])+1);
},valuesCheckSeeding);
Logger.log(filteredArr);
Logger.log(filteredArr.length);
var rangeSeeding = sheetSeeding.getRange(seedingCurrentRow, seedingCurrentColumn, filteredArr.length, seedingNumColumns);
sheetSeeding.getRange('A1').setValue(today);
columnToClear.clearContent();
rangeSeeding.setValues(filteredArr);
/*
//ALTERNATIVE METHOD USING LOOPS
for (var i = 0; i < valuesDATA.length; i++) {
for (var j = 0; j < valuesCheckSeeding.length; j++) {
if (valuesDATA[i][0] == valuesCheckSeeding[j][0]) {
valuesDATA.splice(i, 1);
i--; //account for the splice
break; //go to next i iteration of loop
}
}
}
Logger.log("VALUES DATA:" + valuesDATA);
Logger.log("VALUES CHECK SEEDING: " + valuesCheckSeeding);
//sheetSeeding.getRange('A1').setValue(today);
//rangeSeeding.clearContent();
//rangeSeeding.setValues(valuesDATA); //INCORRECT RANGE HEIGHT, WAS 71 BUT SHOULD BE 1000 - Is splice affecting this?
*/
}//END FUNCTION
V8(ES2016 update):
You can use newer and efficient set class
const array1 = [[1],[2],[3]],
array2 = [[1],[3],[4]],
set = new Set(array2.flat())
console.info(array1.filter(e => !set.has(e[0])))
//expected output [[2]]
You're checking a 2D array. You'd need to use [i][0] and [j][0]
You can try only splicing valuesDATA
Try
for (var i = 0; i < valuesDATA.length; i++) {
for (var j = 0; j < valuesCheckSeeding.length; j++) {
if (valuesDATA[i][0] == valuesCheckSeeding[j][0]) {
valuesDATA.splice(i, 1);
i--; //account for the splice
break; //go to next i iteration of loop
}
}
}
Logger.log(valuesDATA);
Alternatively, try
valuesCheckSeeding = valuesCheckSeeding.map(function(e){return e[0];}); //flatten this array
var filteredArr = valuesDATA.filter(function(e){
return !(this.indexOf(e[0])+1);
},valuesCheckSeeding);
Logger.log(filteredArr);
Working on a project for a class and keep getting this error when I want to reference an location in my 2D array.The project is a video game recommender system using pearson correlations. To get the correlations we are pulling results from a database filled usernames, the video game they ranked, and the rank(rating) they gave it. This is then used to create a userArray(array of all users who have ratings) and a rankArray(2D array pictured below with all games and the ratings users have given it) within the generateArrays function.
The error is coming from the line within my sim_pearson function which calculates the actual correlation value. When I try to reference a rating given by a particular user for a particular game, the error arise. I am unsure why as I have referenced the 2D array in a similar way before and had no issue.
Here is my sim_pearson function where the error occurs.
function sim_pearson(rankArray, person1, person2){
var similaritems = [];
for(var i = 0; i <= 9; i++){
if (rankArray[i][person1] !== 0){
if(rankArray[i][person2] !== 0){
similaritems.push(i);
}
}
}
if (similaritems.length === 0){
return 0;
}
console.log(similaritems);
var n = similaritems.length;
var temp1, temp2, sum1, sum2, sum1Sq, sum2Sq, pSum = 0;
for (var x = 0; x <= n; x++){
var sItem = similaritems[x];
temp1 = rankArray[sItem][person1];
temp2 = rankArray[sItem][person2];
sum1 = sum1 + temp1;
sum2 = sum2 + temp2;
sum1Sq = sum1Sq + Math.pow(temp1, 2);
sum2Sq = sum2Sq + Math.pow(temp2, 2);
//sum of products
pSum = pSum + (temp1 * temp2);
}
var num = pSum - (sum1*sum2/n);
var den = Math.sqrt((sum1Sq-Math.pow(sum1, 2)/n)*(sum2Sq-Math.pow(sum2, 2)/n));
if (den === 0){
return 0;
}
var r = num/den;
return r;
}
Here is where I create the arrays:
var userArray = [];
var rankArray = [];
function generateArray(result){
//generate user array
var i,item;
var temp = 0;
for (i in result.rows) {
item = result.rows[i];
var userExists = false;
for (var x = 0; x<=userArray.length; x++){
if(item.username == userArray[x]){
userExists = true;
}
}
if(userExists === false){
userArray.push(item.username);
}
}
for(var y =0; y<10; y++){
rankArray[y] = [];
for(var z = 0; z<userArray.length; z++){
rankArray[y][z] = 0;
}
}
//creating rankarray
var w, item1;
for(w in result.rows) {
item1 = result.rows[w];
for(var k in userArray) {
if (item1.username == userArray[k]) {
temp = k;
}
}
rankArray[(item1.vgnum - 1)][temp] = item1.rank;
}
}
And here is a picture of our arrays when they are created. userArray is first holding all the users, then rankArray which has an array set up in each index for each game(there are only 10) and within that array are the rankings of all the users(0 is user 1, 1 is user 2, etc). After is the similaritems array which just finds the games that two users have both rated.
The line that I am calling sim_pearson from essentially looks like this:
generateArrays(result);
//comparing the first two users
console.log("Pearson value: "+sim_pearson(rankArray, 0, 1);
Really unsure why this error is occuring and why I cannot set a var equal to a location with the rankArray I made like:
temp1 = rankArray[sItem][person1];
Any help would be fantastic!
This line is probably the problem:
for (var x = 0; x <= n; x++){
It should be x < n. Since n = similaritems.length, the indexes of similaritems run from 0 to n-1. So on the last iteration, when you do:
var sItem = similaritems[x];
it sets sItem = undefined. Then you do:
temp1 = rankArray[sItem][person1];
rankArray[undefined] is undefined, so this tries to access undefined[person1], which is not valid.
I'm trying to write a function that will find which collection of numbers in the array adds up to the largest sum, and puts that number into the new array:
var num = ['267453', '345678', '876787'];
var newArray = [];
I'm actually at a loss here and not sure how to get started on this problem. Can someone help get me off on the right foot?
var num = ['267453', '345678', '876787'];
var sums =[];
num.forEach(function (el) {
string = el.split(''); //split into individual characters
var sum = 0; //have a storage ready
for (var i = 0; i < string.length; i++) { //iterate through
sum += parseInt(string[i],10); //convert from string to int
}
sums.push( sum);
}
Array.prototype.max = function() {
return Math.max.apply(null, this);
};
alert("Max value is: "+sums.max());
Iterate over the strings, split the in to digits sum the digits
var arrayLength = num.length;
var sums = []
for (var i = 0; i < arrayLength; i++) {
var digitsAsChar = num[i].split("");
var tmpSum=0;
var digitsLength = digitsAsChar.length;
for(var y=0; y<digitsLength;y++){
tmpSum = tmpSum+parseInt(digitsAsChar[y]);
}
sums.push(tmpSum)
}
finaly sort the array:
sums.sort():
If I understood your question correctly, you can achieve this rather easily.
var num = ['267453', '345678', '876787'];
var max = -Infinity;
var maxi = 0;
num.forEach(function (el, i) {
var n = el.split('').reduce(function (a, b) {
return parseInt(a,10) + parseInt(b,10);
});
if (n > max) {
max = n;
maxi = i;
}
})
console.log(max); //43
console.log(num[maxi]); //"876787"
Regarding performance, this calls parseInt a number of times more than strictly necessary, if speed is a problem you may want to consider parsing first and summing separately.
Here is the fiddle for this :
var num = ['267453', '345678', '876787'];
var newArray = [];
var html = '';
for(var n=0; n<num.length; n++) {
var len = num[n].length;
count = 0;
for(var i=0; i<len; i++) {
count += parseInt(num[n].substring(i,i+1));
//console.log(count);
}
var temp1 = parseInt(num[n]);
newArray.push(count);
}
newArray = newArray.sort();
newArray = newArray.reverse();
var max = newArray[0];
https://jsfiddle.net/o6mryk1q/1/
I have an array:
var myarray = [1,2,3,4,7,9,12,13,14]
I need to group values like so:
var array_1 = 1,2,3,4
var array_2 = 7
var array_3 = 8
var array_4 = 12,13,14
I need to find a sequences with an arithmetic progression and seperate from other values.
Any ideas?
Check out this solution
function explode(myarray)
{
var multi = [];
var i = j = 0;
for ( key in myarray )
{
if((myarray[key-1]) != (myarray[key]-1))
{
i++;
j=0;
}
if(j==0)
multi[i] = [];
multi[i][j] = myarray[key];
j++;
}
return multi;
}
It returns a multidimentionnal array that you can use in your example like this
var myarray = [1,2,3,4,7,9,12,13,14];
var multi_array = explode(myarray);
var array_1 = multi_array[0];
var array_2 = multi_array[1];
var array_3 = multi_array[2];
var array_4 = multi_array[3];
New update :
You can also remove the j index and use .push to add new elements to your array
function explode(myarray)
{
var multi = [];
var i = 0;
for ( key in myarray )
{
if((myarray[key-1]) != (myarray[key]-1))
i++;
if(!multi[i])
multi[i] = [];
multi[i].push(myarray[key]);
}
return multi;
}
The following seems to work, but displays a slightly different output than the one you expect.
In your example, I think 7 and 9 should be grouped (any sequence of two items is an arithmetic
progression after all). Or if they are not grouped, then 12 should not be grouped with 13 and
14 either, since 12-9 != 13-12
function split(arr) {
if (arr.length < 2) {
return;
}
var delta = undefined;
var start = 0;
for (var idx = 1; idx < arr.length; idx++) {
if (delta === undefined) {
delta = arr[idx] - arr[idx - 1];
}
if (arr[idx] - arr[idx - 1] != delta) {
alert("subarray " + arr.slice(start, idx));
start = idx;
delta = undefined;
}
}
alert("subarray from" + arr.slice(start, arr.length));
}
split([1,2,3,4,7,9,12,13,14]);
arrays = Array();
var c = 0;
array[c][] = myarray[0]);
for (var i = 1; i<myarray.length; i++) {
if (myarray[i-1] +1 != myarray[i])
c++;
array[c][] = push(myarray[i]);
}
not sure the array syntax (might mix up languages here) is correct or whether I understand your problem fully.