【问题标题】:indexOf returning -1 despite object being in the array - Javascript in Google Spreadsheet Scripts尽管对象在数组中,但 indexOf 返回 -1 - Google 电子表格脚本中的 Javascript
【发布时间】:2013-06-11 13:03:31
【问题描述】:

我正在为 Google Docs 电子表格编写一个脚本,以读取导演列表并将其添加到数组中(如果它们尚未出现在数组中)。

但是,对于包含在数组中的元素,我似乎无法让 indexOf 返回 -1 以外的任何内容。

谁能告诉我我做错了什么?或者指出一种更简单的方法?

这是我的脚本:

function readRows() {
var column = SpreadsheetApp.getActiveSpreadsheet().getRangeByName("Director");
var values = column.getValues();
var numRows = column.getNumRows();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];

var directors = new Array();

for (var i = 0; i <= numRows - 1; i++) {
    var row = values[i];
    if (directors.indexOf(row) == -1) {
        directors.push(row);
    } else {

        directors.splice(directors.indexOf(row), 1, row);

    }
}

for (var i = 2; i < directors.length; i++) {
    var cell = sheet.getRange("F" + [i]);
    cell.setValue(directors[i]);
}
};

【问题讨论】:

  • else 块似乎是多余的。它将 row 替换为 row
  • 我还要补充一点,值的“设置”可以更有效地完成,即在循环中使用 setValues() 而不是 setValue()。但我不想让我的回答过于复杂。如果您无法弄清楚如何进行此操作(或在此论坛上找到解决该问题的问答),您可能想发布一个新问题。

标签: javascript arrays google-apps-script google-sheets indexof


【解决方案1】:

当您使用 getValues() 在 Google Apps 脚本中检索值时,您将始终处理一个二维 Javascript 数组(按行然后按列索引),即使所讨论的范围是一列宽。因此,在您的特定情况下,并扩展 +RobG 的示例,您的 values 数组实际上看起来像这样:

[['fred'], ['sam'], ['sam'], ['fred']]

所以你需要改变

var row = values[i];

var row = values[i][0];

顺便说一句,可能值得注意的是,您可以使用表格自带的电子表格功能来实现这一点(直接输入电子表格单元格):

=UNIQUE(Director)

这将随着名为Director 的范围内容的变化而动态更新。话虽如此,您可能有充分的理由想要为此使用 Google Apps 脚本。

【讨论】:

    【解决方案2】:

    这听起来像是 GAS 而不是 JS 的问题。 getValues() 一直有问题。即使documentation says that it is a two dimensional array,您也无法像您期望的那样与它进行比较。虽然如果你使用像values[0][1] 这样的索引语句,你会得到一个基本的数据类型。解决方案(我希望有更好的方法)是将该对象强制转换为 String(),然后将其 split() 转换回您可以使用的数组。

    这是我将使用的代码:

     var column = SpreadsheetApp.getActiveSpreadsheet().getRangeByName("Director");
     var values = column.getValues();
          values = String(values).split(",");
     var myIndex = values.indexOf(myDirector);
    

    如果 myDirector 在值中,您将得到一个数字!= -1。但是,数据中的逗号会导致问题。这仅适用于一维数组。

    在您的情况下:var row = values[i]; row 是一个对象,而不是您要比较的字符串。将您的所有 转换为我上面的数组,您的比较运算符应该可以工作。 (尝试将 row 打印到控制台以查看其内容:Logger.log(row)

    【讨论】:

      【解决方案3】:

      我在将范围作为对象的电子表格函数中遇到了类似的问题。就我而言,我想对一组固定值(在另一个数组中)进行简单搜索。

      问题是,您的“列”变量不包含列——它包含一个二维数组。因此,每个值都是它自己的行(本身就是一个数组)。

      我知道我可以使用电子表格中的现有函数完成以下示例,但这是处理二维数组以搜索值的一个不错的演示:

      function flatten(range) {
        var results = [];
        var row, column;
      
        for(row = 0; row < range.length; row++) {
          for(column = 0; column < range[row].length; column++) {
            results.push(range[row][column]);
          }
        }
        return results;
      }
      
      function getIndex(range, value) {
        return flatten(range).indexOf(value);
      }
      

      所以,由于我想简单地在整个范围内搜索值的存在,我只是将它展平为一个数组。如果您真的在处理 2D 范围,那么这种类型的展平和抓取索引可能不是很有用。就我而言,我正在查看一列以查找两组的交集。

      【讨论】:

        【解决方案4】:

        因为我们使用的是二维数组,2dArray.indexOf("Search Term") 必须有一个完整的一维数组作为搜索词。如果我们想在该数组中搜索单个单元格值,我们必须指定要查找的行。

        这意味着如果我们的搜索词不是数组,我们将使用2dArray[0].indexOf("Search Term")。这样做指定我们要查看数组中的第一“行”。

        如果我们正在查看一个 3x3 的单元格范围并且我们想要搜索第三行,我们将使用 2dArray[2].indexOf("Search Term")

        下面的脚本获取电子表格中的当前行并将其转换为数组。然后它使用indexOf() 方法在该行中搜索"Search Term"

        //This function puts the specified row into an array.
        //var getRowAsArray = function(theRow) 
        function getRowAsArray()
        {
          var ss = SpreadsheetApp.getActiveSpreadsheet();     // Get the current spreadsheet
          var theSheet = ss.getActiveSheet();                 // Get the current working sheet
          var theRow = getCurrentRow();                       // Get the row to be exported
          var theLastColumn = theSheet.getLastColumn();       //Find the last column in the sheet.
        
        
          var dataRange = theSheet.getRange(theRow, 1, 1, theLastColumn); //Select the range
          var data = dataRange.getValues();            //Put the whole range into an array
          Logger.log(data);                            //Put the data into the log for checking
          Logger.log(data[0].indexOf("Search Term"));  //2D array so it's necessary to specify which 1D array you want to search in.
          //We are only working with one row so we specify the first array value,
          //which contains all the data from our row
        }
        

        【讨论】:

          【解决方案5】:

          如果有人看到这篇文章,您可能需要考虑使用下面的库。看起来它对我有用。即使在尝试提供的示例时,我也得到了“-1”的回报(感谢您的建议!)。

          添加 Array Lib(版本 13)并使用 find() 函数后,我得到了正确的行!

          这是我使用的项目密钥:MOHgh9lncF2UxY-NXF58v3eVJ5jnXUK_T

          以及参考文献:

          https://sites.google.com/site/scriptsexamples/custom-methods/2d-arrays-library#TOC-Using

          https://script.google.com/macros/library/d/MOHgh9lncF2UxY-NXF58v3eVJ5jnXUK_T/13

          希望这对其他人也有帮助。

          【讨论】:

            【解决方案6】:

            我遇到了类似的问题。 getValues() 似乎是问题所在。所有其他方法都给了我一个 indexOf = -1

            我使用了 split 方法,并在新创建的数组上执行了 indexOf。有效!

              var col_index = 1;
              var indents_column = main_db.getRange(1,col_index,main_db.getLastRow(),1).getValues();
              var values = String(indents_column).split(","); // flattening the getValues() result
              var indent_row_in_main_db = values.indexOf(indent_to_edit) + 1; // this worked
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-04-13
              • 1970-01-01
              • 1970-01-01
              • 2019-06-08
              • 1970-01-01
              相关资源
              最近更新 更多