[英]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.