Как объединить дубликаты ячеек вместе со скриптом приложения Google?

1

В настоящее время у меня есть список с двумя столбцами. Первый столбец - имя студента, а второй столбец - количество очков, которые у них есть.

Я импортировал этот список из нескольких электронных таблиц, поэтому было много дубликатов по именам учащихся. Я могу удалить дубликаты, но я хочу сохранить подсчет сумм, которые у них есть. Например:

Эми 10 Боб 9 Кэрол 15 Эми 12

превратится в:

Эми 22 Боб 9 Кэрол 15

Это то, что у меня есть до сих пор:

  var target = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = target.getSheetByName("Sheet2");
  var data = sheet.getRange("A2:B1000").getValues();
  var newData = new Array();
  var k = 0
  var finallist = []
  for(i in data){
    k++;
    var row = data[i];
    var duplicate = false;
    for(j in newData){
      if(row[0] == newData[j][0]){
        duplicate = true;
        var storedHour = sheet.getRange("B"+k).getValue();
        var position = finallist.indexOf(row[0]);
        var originalCell = sheet.getRange("B"+(position+1));
        var originalHour = originalCell.getValue();
        originalCell.setValue(originalHour + storedHour);
        sheet.getRange(k,2).setValue("")
        sheet.getRange(k,1).setValue("")
      }
    }
    if(!duplicate){
      newData.push(row);
      finallist.push(row[0])
    }
  }
}

Проблема, с которой я столкнулась, состоит в том, что у нас действительно большой выбор данных, и я боюсь, что это может превысить максимальное время выполнения Google за 5 минут. Есть ли еще один эффективный способ достижения моей цели?

  • 0
    Привет Qilin, что не работает, как вы ожидаете? В чем проблема у вас?
  • 1
    Извините, я забыл поставить актуальную проблему в описании! Как небрежно. Мне просто было интересно, как сделать код более эффективным, потому что я хочу выполнить его в течение 5-минутного максимального времени выполнения Google. Я добавлю это сейчас в описание.
Показать ещё 3 комментария
Теги:
google-apps-script
spreadsheet

2 ответа

1
Лучший ответ

Ваш код работает медленно, потому что методы API таблиц таблиц (например, getRange) занимают много времени и намного медленнее, чем другой код JavaScript.

Вот оптимизированная функция с уменьшенным числом таких вызовов API таблиц:

function calcNumbers()
{
  var target = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = target.getSheetByName("Sheet2");
  var lastRow = sheet.getLastRow();
  var dataRange = sheet.getRange(2, 1, lastRow-1, 2);
  var data = dataRange.getValues();
  var pointsByName = {};

  for (var i = 0; i < data.length; i++)
  {
    var row = data[i];
    var curName = row[0];
    var curNumber = row[1];

    // empty name
    if (!curName.trim())
    {
      continue;
    }

    // if name found first time, save it to object
    if (!pointsByName[curName])
    {
      pointsByName[curName] = Number(curNumber);
    }
    // if duplicate, sum numbers
    else
    {
      pointsByName[curName] += curNumber;
    }
  }

  // prepare data for output
  var outputData = Object.keys(pointsByName).map(function(name){
    return [name, pointsByName[name]];
  });

  // clear old data
  dataRange.clearContent();

  // write calculated data
  var newDataRange = sheet.getRange(2, 1, outputData.length, 2);
  newDataRange.setValues(outputData);
}
  • 0
    Что-то похожее на счетную доску. Мне это нравится.
0

Сортировка перед сравнением позволяет рассматривать следующий элемент только вместо всех элементов для каждой итерации. Выгода от побочных эффектов - результат в финале, абразивный. Сокращение времени выполнения.

function sumDups() {
  var target = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = target.getSheetByName("Sheet2");
  var data = sheet.getRange("A2:B" + sheet.getLastRow()).getValues().sort();
  var finallist = [];
  for(var i = 0; i<= data.length - 1; i++){
    var hours = data[i][1];
    while((i < data.length - 1) && (data[i][0] == data[i+1][0])) {
       hours += data[i+1][1];
       i++;
       };
    finallist.push([data[i][0], hours]);
  };
  Logger.log(finallist);
}

Изменение: простая структура данных с именем, находящимся в первом столбце, позволяет это работать. Для любого более сложного понимания и применения методов, показанных в ответе @Kos, предпочтительнее

Ещё вопросы

Сообщество Overcoder
Наверх
Меню