Скрипт листа Google - прекратите заполнять массив по сравнению с другим, если встречается общее значение - PullRequest
1 голос
/ 04 февраля 2020

Я целый день пытался отфильтровать 2 столбца, содержащих текстовые значения, с помощью простого запроса (A1: B; «выбрать A, где A <> B») или = filter (), поэтому я пробовал создавать сценарии, но я также отсутствует что-то. Таким образом, я хочу нарезать первый массив, заполненный, когда в другом массиве найдено общее значение. Может ли кто-нибудь помочь, пожалуйста? Вот код:

function filterAll(){
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('temp1');
  var lastRow = sheet.getLastRow();

  var data1 = sheet.getRange(1, 4, lastRow).getValues();
  var tab1 = [];
  tab1.push(data1[0]);

  var data2 = sheet.getRange(1, 3, lastRow).getValues();
  var tab2 = [];
  tab2.push(data2[0]);

  // var subarray = []; // for subarray = tab2.slice(1,n)

  for (var n = 1; n < data1.length; n++) {
    if (tab1.join().indexOf(data1[n].join()) == -1) { 
      tab1.push(data1[n])  
    };
  }
  sheet.getRange(1, 2, tab1.length, tab1[0].length).setValues(tab1);

  for (var n = 1; n < data2.length; n++){
    if (tab2.join().indexOf(data2[n].join()) == -1) {
      for (var z = 1; z < data1.length; z++){ 
        if (data2[n] === data1[z]){ 
          break;  
        } else { 
          tab2.push(data2[n]); 
        } 
      }
    }
  }
  sheet.getRange(1, 1, tab2.length, tab2[0].length).setValues(tab2);
}

Ответы [ 2 ]

1 голос
/ 04 февраля 2020

Если вам нужна формула, вы можете попробовать

=FILTER(
  A2:A,
  ISNA(MATCH(A2:A,B2:B4,0)),
  ROW(A2:A)<MIN(ARRAYFORMULA(IFERROR(MATCH(B2:B4,A:A,0))))
)

enter image description here

Если вам нужен сценарий, вы можете использовать основной подход

/**
*
* @param {Array.<Array.<object>>} arr data
* @param {Array.<object>} list the list for comparing
* @param {number} colIndex The column of the data for comparing
*/
function filterUntilAnyOfList_(arr, list, colIndex) {
  var res = [];
  arr.some(function(row) {    
    if(list.indexOf(row[colIndex]) === -1){
      res.push(row);
      return false;
    }
    return true;
  });
  return res.length ? res : '';
}

Для функции в вашем проекте это будет

/**
* Action
*/
function userAction() {
  var data = SpreadsheetApp.getActive()
  .getRange('Filter!A2:A')
  .getValues();
  var list = SpreadsheetApp.getActive()
  .getRange('Filter!B2:B3')
  .getValues()
  .map(function(row) {
    return row[0];
  });
  Logger.log(filterUntilAnyOfList_(data, list, 0));
}

Для пользовательской формулы ее тоже можно использовать

/**
* @customformula
*/
function INLIST(data, list, col) {
  data = Array.isArray(data) ? data : [[data]];
  list = (Array.isArray(list) ? list : [[list]]).map(function(row) {
    return row[0];
  });
  return filterUntilAnyOfList_(data, list, col - 1);
}

enter image description here

Мой образец

Получите ваш выбор!

0 голосов
/ 04 февраля 2020

Исходя из того, что я понимаю по вашей проблеме, я бы предложил:

  • , если вы хотите сохранить только значения, найденные во втором массиве:

    =filter(A1:A,match(A1:A,B1:B,0))

  • , если вы хотите сохранить только значения, которые НЕ найдены во втором массиве:

    =filter(A1:A,isna(match(A1:A,B1:B,0)))

Если я неправильно понял ваш запрос, было бы полезно, если бы вы могли поделиться примером своего листа и описать на конкретных примерах, каков будет ожидаемый результат для данного ввода (как уже было запрошено в комментарии к вашему исходному сообщению).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...