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

надеюсь, это поможет кому-то еще.