0

first time posting on here so be gentle! Haha.

I'm more than happy to post my current code if my explanation doesn't meet everyones standards.

I have an array which I have ripped data from an API stored in it. Each object in the array contains 3 values;

  1. User name
  2. User ID
  3. Current statistic

Each row on my sheet contains these 3 properties and I want to list the last 30 days of value 3.

So on the first day, a row may contain A1 "John" B1 "12345" C1 "5"

The 2nd day it would contain A1 "John" B1 "12345" C1 "20" D1 "5"

3rd day A1 "John" B1 "12345" C1 "40" D1 "20" E1 "5"

I can do this even with my limited knowledge of loops, what I have issues with is if there is a new entry in the array that is NOT on the sheet I need to be able to add it. Then I can continue adding data every day from there.

Thanks in advance.

  function GymStrength1() {

  var ss = SpreadsheetApp.openById("1bXc_AZcAAl09bf0ibfC6vQSY9O3ikpn0Ru7pZ4oZ0g8");
  var sheet = ss.getSheetByName("Strength");
  var currentData = sheet.getDataRange().getValues();

  var response = UrlFetchApp.fetch("https://api.torn.com/faction/?selections=basic,contributors&stat=gymstrength&key=NhNhNbCmgGaqx0vQ");
  var json = response.getContentText();
  var data = JSON.parse(json);

  var totalMembers = data["contributors"]["gymstrength"];
  var activeMembers = [];
  var newData = [];

  // Gets active members and their daily contribution

  for (var obj in totalMembers){

  var playerID = obj;
  var currentStat = data["contributors"]["gymstrength"][obj]["contributed"];
  var currentMember = data["contributors"]["gymstrength"][obj]["in_faction"];

  if (currentMember == "1"){
  activeMembers.push([data["members"][obj]["name"],playerID,currentStat])
  }
  }

  // for each active member, check against sheet first
  // if row contains member, then merge row with member and paste into newData
  // if row doesnt contain member then add member into newData

  var copy = false;
  for (var member in activeMembers){

  for (var i = 1; i < currentData.length; i++){
  var row = currentData[i];

  // updates each row. works fine

  if (activeMembers[member][1] == row[2]){
  newData.push([activeMembers[member][0],activeMembers[member][1],activeMembers[member][2],row[3],row[4]]);
  copy = true;
  }


  }
  if (!copy){
  newData.push([activeMembers[member][0],activeMembers[member][1],activeMembers[member][2],"0","0"]);
  }
  }


  console.log(activeMembers)
  console.log(newData)


    sheet.getRange(2, 2, currentData.length, currentData[0].length).clearContent();
    sheet.getRange(2, 2, newData.length, newData[0].length).setValues(newData);
  }

I'm basing the comparison of the newData array and the sheet on the currentStat value of each entry. If the currentStat of an object in activeMembers is NOT on the sheet, I want the name, playerID and currentStat pushed to the newData array. If the currentStat IS on the sheet, it pushes the name, playerID and currentStat to the newData array as well as copying the rest of the values on that row. I can do that.

I am having trouble with adding entries that are NOT on the sheet, updating them works fine.

Brief example:

activeMembers array has obj name, playerID, currentStat

[
 ['John', '2856', '50'], 
 ['Bob', '2957', '20'],
 ['Peter', '4579', '80']
]

sheet currently only has

[['John', '2856', '40']]

I would like the end result on the sheet to be

  • John 2856 50 40
  • Bob 2957 20
  • Peter 4579 80

John's 40 value has shifted to the right and the current value put in its place.

TheMaster
  • 45,448
  • 6
  • 62
  • 85
  • 4
    Provide [mcve]. – TheMaster Sep 28 '20 at 11:49
  • Can you provide the code you're working on, and clarify what you mean by `I want to list the last 30 days of value 3`? Does this mean you are retrieving the array daily, and want to update the sheet daily? If that's not the case, how you identify the different days for each User? – Iamblichus Sep 28 '20 at 12:49
  • So each day I grab the 3 values in each object in the activeMembers array, if there is a match, then I copy the values from the row, insert the current object values and paste it into the newData array. I only have the first few days for testing, but it will copy upto 30 days when I fix it. – Richy Caldwell Sep 28 '20 at 13:23
  • 2
    Please provide sample data – Cooper Sep 28 '20 at 13:29
  • See: https://stackoverflow.com/questions/2218999/remove-duplicates-from-an-array-of-objects-in-javascript. You can take it from there, hopefully. – Oleg Valter is with Ukraine Sep 28 '20 at 14:36
  • @Iamblichus Rollbacked the edit as there is no indication that OP wants the opposite. If you feel your edit was right, kindly clarify. – TheMaster Sep 28 '20 at 14:47
  • @TheMaster So on the first day, a row may contain A1 "John" B1 "12345" C1 "5" The 2nd day it would contain A1 "John" B1 "12345" C1 "20" D1 "5" 3rd day A1 "John" B1 "12345" C1 "40" D1 "20" E1 "5" – Iamblichus Sep 28 '20 at 14:48
  • 1
    @TheMaster What I understand is the value which is currently in the sheet gets shifted right. – Iamblichus Sep 28 '20 at 14:50
  • 1
    @Iamblichus Thank you for the clarification. I feel you are right and rollbacked my previous edit. – TheMaster Sep 28 '20 at 14:53
  • Yeah.. so what will happen is once all 30 days (columns) have a value, when the currentStat is looked up and added in, the last value gets dropped so there will only ever be a maximum of 30 values to get my 30 days worth of data – Richy Caldwell Sep 28 '20 at 15:11
  • Ah. I fixed it myself. The "var copy = false;" line should have been within the activeMembers array... One line lower than it currently is. Then the "if (!copy){" later on should have been "if (copy){". Thanks for the replies. Appreciated. Maybe next time I'll look more carefully at what I'm doing! – Richy Caldwell Sep 28 '20 at 21:20

1 Answers1

1
  • Create a map of sheet data: id=>oldStat
  • Modify the activeMembers array in place using the map data

/*<ignore>*/console.config({maximize:true,timeStamps:false,autoScroll:false});/*</ignore>*/
const activeMembers = [
  ['John', '2856', '50'],
  ['Bob', '2957', '20'],
  ['Peter', '4579', '80'],
];
const sheetData = [['John', '2856', '40']];
const sMap = new Map();
sheetData.forEach(([, id, oldStat]) => sMap.set(id, oldStat));
activeMembers.forEach(row =>
  row.push(sMap.has(row[1]) ? sMap.get(row[1]) : '')
);
console.info({sMap,activeMembers});
console.log(JSON.stringify(activeMembers));
<!-- https://meta.stackoverflow.com/a/375985/ -->    <script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
TheMaster
  • 45,448
  • 6
  • 62
  • 85