indexOf возвращает -1 несмотря на то, что объект находится в массиве-Javascript в скриптах Google Spreadsheet
Я пишу скрипт для таблицы 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]);
}
};
5 ответов
при получении значений в сценарии Google Apps с getValues(), вы всегда будете иметь дело с 2D-массивом Javascript (индексированным строкой, а затем столбцом), даже если рассматриваемый диапазон имеет ширину одного столбца. Так что в вашем конкретном случае, и расширяя пример + RobG, ваш values
массив будет выглядеть примерно так:
[['fred'], ['sam'], ['sam'], ['fred']]
так что вам нужно будет изменить
var row = values[i];
to
var row = values[i][0];
в стороне, это возможно, стоит отметить, что для этого вы можете использовать функцию электронной таблицы, родную для листов (набранную непосредственно в ячейку электронной таблицы):
=UNIQUE(Director)
это будет динамически обновляться как содержимое диапазона с именем Director
изменения. Тем не менее, вполне может быть веская причина, по которой вы хотели использовать скрипт Google Apps для этого.
это звучит как проблема с газом, а не 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. Однако запятые в ваших данных вызовут проблемы. И это будет работать только с массивами 1Д.
в вашем случае: var row = values[i];
строка - это объект, а не строку, которую вы хотите сравнить. Конвертируйте все свои значения к массиву, как у меня выше, и ваши операторы сравнения должны работать. (пытаться печать строка в консоли, чтобы увидеть, что он говорит: Logger.log(row)
)
потому что мы работаем с 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
}
я столкнулся с аналогичной проблемой с функцией электронной таблицы, которая приняла диапазон в качестве объекта. В моем случае я хотел выполнить простой поиск фиксированного набора значений (в другом массиве).
проблема в том, что ваша переменная" column " не содержит столбец-она содержит 2D-массив. Поэтому каждое значение является собственной строкой (само по себе массивом).
Я знаю, что мог бы выполнить следующий пример, используя существующую функцию в электронной таблице, но это приличная демонстрация о работе с 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 диапазонами, то этот тип выравнивания и захвата индекса может быть не очень полезным. В моем случае я просматривал столбец, чтобы найти пересечение двух наборов.
Если кто-то сталкивается с этим сообщением, вы можете рассмотреть возможность использования библиотеки ниже. Похоже, у меня получится. Я получал возврат " -1 " даже при попытке предоставить примеры (спасибо за предложения!).
после добавления массива 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
надеюсь, это поможет кому-то еще.