#javascript #google-apps-script #google-sheets
#javascript #google-apps-script #google-sheets
Вопрос:
Я хочу уменьшить вызовы sheet.getRange в следующей функции, потому что время выполнения истекло.
Я попытался переупорядочить циклы и проанализировать данные в виде двойного массива, однако размер моей электронной таблицы меняется каждый день, и мне нужно иметь возможность ссылаться на столбцы только по имени.
function runDuplicateRemover() {
var sheet= SpreadsheetApp.getActive().getSheetByName('Sheet 1');
var rangeData = sheet.getDataRange();
var lastRow = rangeData.getLastRow();
var Cdata = sheet.getDataRange().getValues();
// here I am accessing the column which is used to find duplicates
var colCRM = Cdata[0].indexOf("CRM ID") 1;
var arrayOfDuplicates = [];
for(i=1; i<lastRow; i ){
var cellToCompare = sheet.getRange(i 1,colCRM);
// I am just changing all the colors to see the execution
cellToCompare.setBackground("#88b4fc");
var crmToCompare =cellToCompare.getValue();
//checks to see that this value is not already contained in the rows to delete
if (!cellToCompare.isBlank() amp;amp; (arrayOfDuplicates.indexOf(i) 1)==0 ){
arrayOfDuplicates.push(i);
cellToCompare.setBackground("#f9d9f9");
for (j = i 1; j<lastRow; j ) {
var cellCurrent = sheet.getRange(j 1,colCRM);
cellCurrent.setBackground("#f2fc88");
var crmCurrent = cellCurrent.getValue();
if (crmToCompare == crmCurrent) {
arrayOfDuplicates.push(j);
cellCurrent.setBackground("#fc92f1");
}
}
//pops last value since that's the only one I want to keep
sheet.getRange(arrayOfDuplicates.pop() 1,colCRM).setBackground("#dbf7d4");
}
}
for (t = arrayOfDuplicates.length-1; t>=0; t--) {
sheet.deleteRow(arrayOfDuplicates[t] 1);
}
}
Я хотел бы уменьшить количество вызовов sheet.getRange, однако я не знаю, как удалить строки, а затем вернуть данные обратно на лист, не нарушая порядок столбцов.
Комментарии:
1. Вы могли бы использовать Set. В каждой ячейке вы проверяете, существует ли элемент в наборе. Если элемент существует в наборе, то вы знаете, что это дубликат (и делайте с ними то, что хотите). Если элемента нет в наборе, то вы добавляете его, поскольку набор содержит только уникальные элементы, без дубликатов.
2. @acarlstein как бы с помощью set уменьшить мои вызовы getRange? Я уже проверяю, существует ли элемент с массивом.
3. Набор, как правило, использует хэш-таблицу в качестве базовой структуры данных, поэтому проверка элемента может быть O(1), а поиск элемента также может быть O(1).
4. Позвольте мне немного расширить свой комментарий. Вы используете массив дубликатов, а затем выполняете поиск с помощью
indexOf()
. Это означает, что ваша временная сложностьO(n)
. Почему? Поскольку в худшем случае вы должны перебирать весь массив, пока не найдете значение. Если вместо этого использовать Set , время может быть сокращено доO(1)
по временной сложности, потому чтоSet
используетHashTable
. Способ доступа к элементам намного эффективнее; следовательно, вы можете выполнить то же самое, но быстрее.5. Неважно. В Javascript ‘Set’ не реализован с использованием хэш-таблицы, как в других языках (и языках сценариев). Метод
has()
являетсяO(n)
. Вам придется реализовать это самостоятельно или найти кого-то в GitHub, кто его создал.