indexOf()在数组中找不到值

问题描述 投票:0回答:1

基于此post,我正在研究一个概念证明,以通过Google表单捕获项目请求,通过电子邮件发送以供批准,并将批准结果发回到Google工作表的相应行中。使用时间戳作为键从数组中搜索该行。

我面临2个挑战:首先,阵列中的时间戳采用不同的格式,有时相差1秒。我通过调整格式以使其与数组值匹配来进行了调整,如果第一次时间戳搜索失败,则运行第二次搜索。我希望这是万无一失的,但请告诉我是否有更好的方法。我不知道为什么有时会有1秒的差异。

我被困在第二个挑战:我无法成功搜索数组中的时间戳记。 indexOf()始终返回值-1。

非常感谢您的帮助。如果需要,请详细说明,我是新手。

这是我的代码:

function sendEmail(e) {
  // Response columns: Timestamp    Requester Email Item    Cost
  var email = e.namedValues["Requester Email"];
  var item = e.namedValues["Item"];
  var cost = e.namedValues["Cost"];
  var timestamp = e.namedValues["Timestamp"];

  var url = ScriptApp.getService().getUrl();

  // Enhancement: include timestamp to coordinate response  
  var options = '?approval=%APPROVE%&timestamp=%TIMESTAMP%&reply=%EMAIL%'
         .replace("%TIMESTAMP%",encodeURIComponent(e.namedValues["Timestamp"]))
         .replace("%EMAIL%",e.namedValues["Requester Email"])         
  var approve = url+options.replace("%APPROVE%","Approved"); 
  var reject = url+options.replace("%APPROVE%","Rejected");

  var html = "<body>"+
                "<h2>Please review</h2><br />"+
                "Request from: " + email + "<br />"+
                "For: "+item +", at a cost of: $" + cost + "<br /><br />"+ 
                "<a href="+ approve +">Approve</a><br />"+
                "<a href="+ reject +">Reject</a><br />"+
             "</body>";

  MailApp.sendEmail(Session.getEffectiveUser().getEmail(),
                    "Approval Request", 
                    "Requires html",
                    {htmlBody: html});  
}


function doGet(e) {

  var answer = (e.parameter.approval === 'Approved') ? 'Buy it!' : 'Not this time, Keep saving'; 
  var timestamp = e.parameter.timestamp;
  var newtimestamp = Utilities.formatDate(new Date(timestamp), "GMT+8", "EEE MMM dd yyyy HH:mm:ss 'GMT+0800 (SGT)'");  //reformat timestamp to match the ones in the data array
  var approvalCol = 5;

  MailApp.sendEmail(e.parameter.reply, "Purchase Request", 
                    "Your manager said: "+ answer);   

  // Update approval status back to the sheet
  var wsID = "<myworksheetID>";
  var sheet = SpreadsheetApp.openById(wsID).getSheetByName("Requests");
  var data = sheet.getDataRange().getValues();

  var oneColArray = new Array();
  for(i=0;i<data.length;++i){
     oneColArray.push(data[i][0]); // taking index 0 means I'll get column A of each row and put it in the new array
  }

  var row = oneColArray.indexOf(newtimestamp);

  Logger.log("\ntimestamp: " + timestamp + "\n\n" + "newtimestamp: " + newtimestamp + "\n\n" + "oneColArray: \n" + oneColArray);

  if (row < 0) {                                     //not found
    //Lower timestamp by 1 second. Sometimes there is a 1-second difference than the one in the array. I don't know why
    var dateString = Utilities.formatDate(new Date(timestamp), "GMT+8",'EEE, d MMM yyyy HH:mm:ss');
    var date = new Date(dateString);
    var revisedtimestamp = new Date((date.getTime() - (1/(24*60*60)*1000)));

    // now search again using the adjusted timestamp
    var row = oneColArray.indexOf(revisedtimestamp); 

    if (row < 0) {
       Logger.log("\ntimestamp: " + timestamp + "\n\n" + "newtimestamp: " + newtimestamp + "\n\n" + "oneColArray: \n" + oneColArray + "\n\n" + "revisedtimestamp: " + revisedtimestamp);
       throw new Error ("Request not found in list.");
    } else {
    sheet.getRange(row + 1, approvalCol).setValue(e.parameter.approval);
    }
  } else {
    sheet.getRange(row + 1, approvalCol).setValue(e.parameter.approval);
    }
}



arrays timestamp indexof
1个回答
0
投票

我基于此post找到了解决方案。

我更改了此行:

var row = oneColArray.indexOf(newtimestamp); 

以此将数组转换为字符串,并且indexOf()返回找到时间戳第一次出现的起点。根据返回值,我只计算了工作表中的哪一行:

var row = oneColArray.join().indexOf(newtimestamp); 

我更喜欢的另一种变化是遍历数据数组的timestamp列,在每个循环中,在执行indexOf()之前将值转换为字符串。我只需要在[i]上加1即可在工作表中获得实际的行。

for (var i = 0; i < data.length; ++i) {
       var row = data[i][0].toString().indexOf(newtimestamp);
    if (row > -1) {
      var a = i;
      break;
    }
  }
© www.soinside.com 2019 - 2024. All rights reserved.