Сбор всех уникальных значений из одного столбца и вывод их в другом столбце..?

У меня есть эта форма электронной таблицы:

 A   B   C  D
abc abc abc 1
def ghi jkl 1
mno pqr stu 3
vwx yza bcd 4
mno pqr stu 5
mno pqr stu 5
vwx yza bcd 5
mno pqr stu 1

Где первые 3 столбца - это просто данные типа string. Столбец D имеет целые числа с повторяющимися числами. У меня вопрос, как вывести пятую колонку так:

 A   B   C  D E
abc abc abc 1 1
def ghi jkl 1 3
mno pqr stu 3 4
vwx yza bcd 4 5
mno pqr stu 5
mno pqr stu 5
vwx yza bcd 5
mno pqr stu 1

Он выводит только уникальные номера из столбца D.

Я представлял себе выполнение оператора if/else в цикле for или while, который проверяет каждую ячейку в "D" и сохраняет любое значение, которое ранее "не видели" в массиве. Затем вывести массив в столбце E.

Мне было интересно, если есть более эффективный способ сделать это. Кроме того, выше, это только маленький пример. Скорее всего, диапазон данных находится в диапазоне 400. (Мудрый ряд. Столбцы только 4 или 5, включая новый выходной столбец.)

Заранее спасибо.

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

2 ответа

Решение

Вот способ сделать это... вероятно, не единственный, но, вероятно, не плохо...

Я добавил несколько журналов, чтобы увидеть промежуточные результаты в регистраторе.

function keepUnique(){
  var col = 3 ; // choose the column you want to use as data source (0 indexed, it works at array level)
  var sh = SpreadsheetApp.getActiveSheet();
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var data=ss.getDataRange().getValues();// get all data
  Logger.log(data);
  var newdata = new Array();
  for(nn in data){
    var duplicate = false;
    for(j in newdata){
      if(data[nn][col] == newdata[j][0]){
        duplicate = true;
      }
    }
    if(!duplicate){
      newdata.push([data[nn][col]]);
    }
  }
  Logger.log(newdata);
  newdata.sort(function(x,y){
  var xp = Number(x[0]);// ensure you get numbers
  var yp = Number(y[0]);
  return xp == yp ? 0 : xp < yp ? -1 : 1;// sort on numeric ascending
});
  Logger.log(newdata);
 sh.getRange(1,5,newdata.length,newdata[0].length).setValues(newdata);// paste new values sorted in column of your choice (here column 5, indexed from 1, we are on a sheet))
  }

РЕДАКТИРОВАТЬ:

После ответа Теодроса, формула электронной таблицы - действительно элегантное решение, я никогда не думаю об этом, но должен!!!;-)

=SORT(UNIQUE(D1:D))

дает точно такой же результат...

Вы можете сделать это внутри таблиц Google с помощью UNIQUE функция.
Вот документация для всех доступных функций.
(Ты находишь UNIQUE в Filter категория)

Скорее всего, вы хотите вставить в ячейку E1:

=UNIQUE(D1:D)

Это заполнит колонку E с уникальными значениями из всех столбцов D сохраняя порядок. Кроме того, это будет динамически обновлять и отражать все изменения, сделанные в столбце D,

Чтобы сделать это из google-apps-script:

SpreadsheetApp.getActiveSheet()
 .getRange("E1").setFormula("=UNIQUE(D1:D)");

В настоящее время в движке V8 самый простой способ сделать это - использовать Set:

/**
 * @returns {Object[]} Gets unique values in a 2D array
 * @param {Object[][]} array2d
 * @private
 */
const getUnique_ = array2d => [...new Set(array2d.flat())];

/**
 * Gets Values from a column, makes it unique and sets the modified values
 *   to the next column
 * @param {string} sheetName
 * @param {number} column Number of the column to uniquify
 * @param {number} headers Number of headers
 * @returns void
 */
const uniquifyAColumn = (sheetName = 'Sheet1', column = 3, headers = 1) => {
  const sh = SpreadsheetApp.getActive().getSheetByName(sheetName),
    rg = sh.getRange(1 + headers, column, sh.getLastRow() - headers, 1),
    values = rg.getValues(),
    uniqueValues = getUnique_(values).map(e => [e]);
  rg.offset(0, 1, uniqueValues.length).setValues(uniqueValues);
};

Вот сценарий для получения уникального списка непустых значений в столбце с учетом листа, на котором он находится, и местоположения заголовка столбца с использованием массива для хранения значений и indexOf для поиска дубликатов. Затем вы можете записать массив где угодно.

headerLocation - это объект Location:

var Location = function(sheet, row, col) {
  this.sheet = sheet;
  this.row = row;
  this.col = col;
  this.addRow = function() { this.row = this.row + 1; }
  this.addCol = function() { this.col = this.col + 1; }
  this.getValue = function() { return sheet.getRange(this.row, this.col).getValue(); }
  this.toString = function() { return "(" + this.row + "," + this.col + ")"; }
}

Это функция для чтения столбца и возврата уникальных значений:

/**
* Get unique values in column, assuming data starts after header
* @param {Sheet} sheet - Sheet with column to search
* @param {object} headerLocation - row and column numbers of the column header cell
* @returns {array} list of unique values in column
*/
function getUniqueColumnValues(sheet, headerLocation) {
  let startRow = headerLocation.row + 1;
  let lastRow = sheet.getLastRow();
  let values = [];
  for (i = startRow ; i <= lastRow ; i++) {
    let value = sheet.getRange(i, headerLocation.col).getValue();
    if ((value != "") && (values.indexOf(value) == -1)) {
      values.push(value);
    }
  }  
  return values;
}

Или, используя Location, чтобы найти значения:

function getUniqueColumnValues(sheet, headerLocation) {
  let values = [];
  let searchLocation = new Location(sheet, headerLocation.row + 1, headerLocation.col);
  let lastRow = sheet.getLastRow();
  while (searchLocation.row <= lastRow) {
    let value = searchLocation.getValue();
    if (values.indexOf(value) == -1) {
      values.push(value);
    }
    searchLocation.addRow();
  }
  return values;
}
Другие вопросы по тегам