Блог

Массивы Google Apps Script и JavaScript. Метод .filter()

Краткое описание метода

Метод .filter() последовательно сравнивает все элементы массива с условием фильтра, указанным в callback функции (функции обратного вызова). То есть метод, по сути, представляет собой цикл for, внутри которого callback функция последовательно обрабатывает все элементы массива.

Метод .filter() может передавать в callback функцию три параметра:

  1. текщее значение элемента массива item
  2. необязательный параметр index - индекс текущего элемента
  3. необязательный и редко используемый параметр array

Для того, чтобы элемент, удовлетворяющий условию фильтра, был выбран, callback функция должна вернуть значение true.

Все элементы, для которых callback функция вернула знечение true, собираются в отдельный массив, который может быть сохранён в новом массива (в примерах ниже это массив result2).

В трёх вариантов примера, представленных ниже (examples #1, #2, #3) рассмотрено одно и то же условие фильтра - отобрать все элементы массива со значением > 3.

В последнем примере (наиболее оптимальным с точки зрения краткости кода) логическое выражение, вместо оператора if , поставлено непосредственно в return . Поскольку, как известно, логическое выражение может принимать только 2 значения: true или false.

const arr = [1, 2, 9, 4, 1, 6, 5];
    
    let result = arr.filter((item, idx, arr) => console.log(item, idx, arr));
//  [20-06-15 14:53:21:082 EEST] 1 0 [ 1, 2, 9, 4, 1, 6, 5 ]
//  [20-06-15 14:53:21:084 EEST] 2 1 [ 1, 2, 9, 4, 1, 6, 5 ]
//  [20-06-15 14:53:21:085 EEST] 9 2 [ 1, 2, 9, 4, 1, 6, 5 ]
//  [20-06-15 14:53:21:086 EEST] 4 3 [ 1, 2, 9, 4, 1, 6, 5 ]
//  [20-06-15 14:53:21:087 EEST] 1 4 [ 1, 2, 9, 4, 1, 6, 5 ]
//  [20-06-15 14:53:21:089 EEST] 6 5 [ 1, 2, 9, 4, 1, 6, 5 ]
//  [20-06-15 14:53:21:090 EEST] 5 6 [ 1, 2, 9, 4, 1, 6, 5 ]
    
    console.log(result);
//  [20-06-15 14:53:21:091 EEST] []  

// variant #1
  let result2 = arr.filter(item => {
      if (item > 3) {
        return true;
      } else {
        return false;
      };
    });
    
// variant #2
    result2 = arr.filter(item => {
      return item > 3;
    });


// variant #3
    result2 = arr.filter(item => item > 3);
    
    console.log(result2); // [ 9, 4, 6, 5 ]
    
    var sf = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
    let data = sf.getDataRange().getValues().slice(1);
    
    console.log(data);
//  [ [ '', false, 'apples', 5 ],
//    [ '', true, 'carrots', 12 ],
//    [ '', false, 'grapes', 4 ],
//    [ '', false, 'plums', 3 ],
//    [ '', true, 'strawberry', 9 ],
//    [ '', false, 'perches', 4 ],
//    [ '', false, 'bananas', 1 ] ]   

    let newData = data.filter(item => item[1]);

    console.log(newData); 
// [ [ '', true, 'carrots', 12 ], 
//   [ '', true, 'strawberry', 9 ] ]

И ещё одни полезный скрипт, который не вошёл в это видео - скрипт, который фильтрует ТОЛЬКО уникальные значения.

Идея очень проста: для каждого элемента массива находится его индекс и сравнивается с текущим индексом значения этого элемента в массиве. Если элемент не встретился ранее, то значения индексов будут равны, и функция uniqValue вернёт true .

В первом примере, для лучшего понимания алгоритма, функция uniqValue написана отдельно. Во втором - непосредственно "встроена" в метод .filter

let arrayNotUniq = [1, 5, 9, 5];

//variant #1

function uniqValues(item, index, arr) {
  return arr.indexOf(item) === index;
}

let arrayUniq = arrayNotUniq.filter(uniqValues)                        // [1, 5, 9]



//variant #2

  let arrayUniq = arrayNotUniq.filter((item, index, arr) => {
    return arr.indexOf(item) === index;
  });                                                                                                     // [1, 5, 9]

Дополнительную информацию вы можете найти в этом видео: