-4

Been trying this the whole day but to no avail. I need to be able to return each value in an array to google sheet repeatedly, (n-1) number of times, with n as the array.length. This array.length is expected to be inconsistent, depending on user input via google form.

User is expected to enter some code names in a text field in google form, separating each code name with symbol '||'. Each code name must be unique but still there would be a validation check to remove duplicates before other process. Then return output in rows in the google sheet repeatedly.

Eg. Input of 5 code names in array = ['Marvell','Xtortion','Ambiguous','Exhale','Xtortion']
My code as below:-

//by Bjorn | https://stackoverflow.com/questions/881085/count-the-number-of-occurrences-of-a-character-in-a-string-in-javascript
var cname=sheet.getRange(2,1).getValue();
var code=cname.split("||");
var codename=[...new Set(code)]; //get unique values first
var count=cname.split("||").length - 1;  // to get freq to repeat output of same value.
// ['Marvell','Xtortion','Ambiguous','Exhale']
// array.length is 4, output each value being returned to google sheet start from row 3 in col A should be 3 times (n-1)
  
  var lrow=sheet.getLastRow();
  for(var i=1;i<=count;i++){
    for(var j=0;j<=count;j++){
       sheet.getRange(lrow+1,1,i,1).setValue([j]);
           var lrow=sheet.getLastRow();
   }
  }
}

Expected Output :
Marvell
Marvell
Marvell
Xtortion
Xtortion
Xtortion
Ambiguous
Ambiguous
Ambiguous
Exhale
Exhale
Exhale

But my code produced as below :
Marvell
Xtortion
Ambiguous
Exhale
Marvell
Marvell
Xtortion
Xtortion
Ambiguous
Ambiguous
Exhale
Exhale
Marvell
Marvell
Marvell
Xtortion
Xtortion
Xtortion
Ambiguous
Ambiguous
Ambiguous
Exhale
Exhale
Exhale

Please help to correct my code. Thank you in advance.

dell
  • 171
  • 13

2 Answers2

2

The code you posted is printing the indexes, not what you listed in the post.

  1. You're not calculating the count correctly. In your code, you set the count to 4. You should use the codename instead of resplitting the original string.
  2. Your first loop should be iterating over the unique values, not count. Think of how you wrote in the post, "I need to be able to return each value in an array to google sheet repeatedly". The value comes first, then you repeat it.
  3. In your for loops, you switch between between starting with 0 or 1. Stick with one of those as it will help you from getting confused with your conditions. (Example: for(var i=0;i<=3;i++) {} will loop 4 times, not 3.)
  4. You shouldn't use i in sheet.getRange(lrow+1,1,i,1) because that should define how many rows you're inserting, which will incorrectly increase with every loop iteration. (Anyway, it doesn't really hurt because you're using setValue() which ignores that height anyway.)
  5. setValue([j]); will only print the index. You need to pass it the correct value codename[i].
  6. Best practices suggest that you use batch operations where possible, so I suggest you setValues().

Below are two functions that do the same thing. The first one is your code, but merely fixed. The second function is an improved version using batch operations and variable names that are, for me, easier to understand.

function fixed() {
  var sheet = SpreadsheetApp.getActive().getSheetByName('Sheet1');
  //by Bjorn | https://stackoverflow.com/questions/881085/count-the-number-of-occurrences-of-a-character-in-a-string-in-javascript
  var cname = sheet.getRange(2,1).getValue();
  var code = cname.split("||");
  var codename = [...new Set(code)]; //get unique values first
  var count= codename.length - 1;  // to get freq to repeat output of same value.
  // ['Marvell','Xtortion','Ambiguous','Exhale']
  // array.length is 4, output each value being returned to google sheet start from row 3 in col A should be 3 times (n-1)
  
  var lrow=sheet.getLastRow();
  for(var i=0;i<codename.length;i++){
    for(var j=0;j<count;j++){
      sheet.getRange(lrow+1,1).setValue(codename[i]);
      var lrow=sheet.getLastRow();
    }
  }
}

function improved() {
  var sheet = SpreadsheetApp.getActive().getSheetByName("Sheet1");
  var input = sheet.getRange(2,1).getValue();
  var uniqueValues = [...new Set(input.split("||"))]; 
  var frequency = uniqueValues.length - 1;
  
  var output = [];
  for (var i = 0; i < uniqueValues.length; i++) {
    for (var j = 0; j < frequency; j++) {
      output.push([uniqueValues[i]]);
    }
  }
  
  sheet.getRange(sheet.getLastRow()+1, 1, output.length, output[0].length).setValues(output);
}
Diego
  • 9,261
  • 2
  • 19
  • 33
  • Wow! You rock, @Diego! Am so amazed with how detailed you put it and give the precise solution of what am looking for. and bonus, you even showed the correction to my code. I tested both. But I am very much prefer yours because I noticed that your code processes the result a lot faster than mine as I saw how the output in the sheet while running the code. Alhamdulillah...!! You're my saviour, Sir! :) – dell Sep 09 '20 at 20:42
0

See this post the anser there is:

function fillArray(value, len) {
  var arr = [];
  for (var i = 0; i < len; i++) {
    arr.push(value);
  }
  return arr;
}
RemcoE33
  • 1,551
  • 1
  • 4
  • 11
  • I tried this code. in the Logs i could see all the values in the array appears but when I run it, the output just show on the first value of the array and only came out once. Not sure whether I used wrong command for it to return as how I desired it to be or this solution is just not for my case for now. but thanks for sharing. – dell Sep 09 '20 at 20:38