9

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

6 回答 6

6

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

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

所以你需要改变

var row = values[i];

var row = values[i][0];

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

=UNIQUE(Director)

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

于 2013-06-11T21:38:26.263 回答
3

这听起来像是 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):)

于 2015-05-10T19:52:10.857 回答
2

I ran into a similar problem with a spreadsheet function that took a range as an object. In my case, I was wanting to do a simple search for a fixed set of values (in another array).

The problem is, your "column" variable doesn't contain a column -- it contains a 2D array. Therefore, each value is it's own row (itself an array).

I know I could accomplish the following example using the existing function in the spreadsheet, but this is a decent demo of dealing with the 2D array to search for a value:

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);
}

So, since I wanted to simply search the entire range for the existance of a value, I just flattened it into a single array. If you really are dealing with 2D ranges, then this type of flattening and grabbing the index may not be very useful. In my case, I was looking through a column to find the intersection of two sets.

于 2013-09-05T08:46:25.453 回答
2

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

这意味着我们使用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
}
于 2016-08-29T15:25:44.413 回答
1

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

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

于 2015-05-17T03:34:46.170 回答
0

我有一个类似的问题。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
于 2020-09-05T17:21:02.023 回答