Поиск совпадений из 2-х диапазонов и замена совпадений определенным значением, какой-либо способ оптимизации? - PullRequest
1 голос
/ 23 октября 2019

Это образец листа. Из этого

1    Search area       Bounty list  Bullet      
2      a    i   z       a   b   c   abc
3      e    b   d       d   e   f   def
4      y    f   h       g   h   i   ghi
5                               
6      1    2   3   4   5   6   7   8
7                Column #

К этому

1    Search area          Bounty list   Bullet      
2      abc  ghi z         a   b   c     abc
3      def  abc def       d   e   f     def
4      y    def ghi       g   h   i     ghi
5                               
6       1    2   3   4    5   6   7      8
7                Column #

Принимается значение «bounty» из «списка bounty», начиная с (2,5) или «a», поиск вокруг«Область поиска» в последовательности от a, i, z, e, b, d, y, f, h. Затем, если он находит ячейку или несколько ячеек, равных значению «щедрость», то он помещает значение «пуля» из столбца 8 в текущей строке «щедрость» в эти ячейки. Процесс будет повторяться в последовательности a, b, c, d, e, f, g, h, i в «списке щедростей». Оба процесса перемещаются влево и вниз.

function menuItem1()
{
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var target = sheet.getDataRange().getValues();  

  for (var BountyRow = 2; BountyRow<target.length; BountyRow++)//switching rows in bounty list//
  {
    var bullet = sheet.getRange(BountyRow, 8).getValue(); //cell value to paste on targets// 
    for (var BountyColumn = 5; BountyColumn<8; BountyColumn++) //switching columns in bounty list//
    {
    var bounty = sheet.getRange(BountyRow, BountyColumn).getValue();  // cell value to search for//
    if (bounty !=0)
      {
        for (var SearchRow = 1; SearchRow<target.length; SearchRow++) //switching row on search area//
        {
          for(var SearchColumn = 0; SearchColumn<4;SearchColumn++)//switching column on search area//
          {

            if(target[SearchRow][SearchColumn] == bounty) //if search target is found//
            {
              var found = target[SearchRow][SearchColumn];
              sheet.getRange(SearchRow+1, SearchColumn+1).setValue(bullet);
              Logger.log((found)+ " in "+"row"+(SearchRow+1)+", column"+(SearchColumn+1));
            }
          }
        }
      }
    }
  }
}

Он включает в себя тысячи поисков, которые всегда используют больше минуты, и мне было интересно, есть ли более эффективный способ сделать это?

1 Ответ

0 голосов
/ 23 октября 2019

Чтобы оптимизировать код, вам нужно сделать две вещи:

  1. Вместо использования getValue() и setValue() для каждой ячейки (что замедляет код)

    • извлекает весь ваш список вознаграждений и выполняет поиск данных один раз, с помощью getValues()
    • присваивает значения массиву
    • заменяет совпадения в массиве
    • установить обновленные значения массива обратно в диапазон с помощью setValues()
  2. Использовать indexOf () и map () чтобы найти совпадения и заменить их более эффективно

Образец:

function menuItem1(){
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var lastRow=sheet.getLastRow();
  var searchValues=sheet.getRange(2,1,lastRow-2+1,3).getValues();
  var bountyValues=sheet.getRange(2,5,lastRow-2+1,3).getValues();
  var bulletValues=sheet.getRange(2,8,lastRow-2+1,1).getValues();
  for (var i = 0; i<bountyValues.length; i++){
    for (var j = 0; j<bountyValues[0].length; j++){
      if (bountyValues[i][j] !=0){        
        replaceValues(searchValues, bountyValues[i][j], bulletValues[i][0]);
      }
    }
  }
  sheet.getRange(2,1,lastRow-2+1,3).setValues(searchValues)
}
function replaceValues(search, bounty, bullet) {
  for(var k=0;k<search.length;k++){
    search[k]=search[k].map(function(search) {
      var regex=new RegExp("\\b"+bounty+"\\b","g");
      return search.toString().replace(regex, bullet);
    });
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...