繁体   English   中英

尽管对象在数组中,但 indexOf 返回 -1 - Google 电子表格脚本中的 Javascript

[英]indexOf returning -1 despite object being in the array - Javascript in Google Spreadsheet Scripts

我正在为 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]);
}
};

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

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

所以你需要改变

var row = values[i];

var row = values[i][0];

顺便说一句,可能值得注意的是,您可以使用 Sheets 原生的电子表格函数来实现这一点(直接输入到电子表格单元格中):

=UNIQUE(Director)

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

这听起来像是 GAS 而不是 JS 的问题。 我一直在使用getValues() 时遇到问题。 即使文档说它是一个二维数组,您也无法像您期望的那样与它进行比较。 尽管如果您使用诸如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是一个对象,而不是您要比较的字符串。 将您的所有转换为我上面的数组,您的比较运算符应该可以工作。 (尝试将打印到控制台以查看其内容: Logger.log(row)

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

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

我知道我可以使用电子表格中的现有函数完成以下示例,但这是处理 2D 数组以搜索值的体面演示:

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 范围,那么这种类型的展平和抓取索引可能不是很有用。 就我而言,我正在查看一列以找到两个集合的交集。

因为我们使用的是二维数组, 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
}

如果有人看到这篇文章,您可能需要考虑使用下面的库。 看起来它对我有用。 即使在尝试提供的示例时,我也得到了“-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

希望这也能帮助其他人。

我有一个类似的问题。 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM