8

我有这种形式的电子表格:

 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 列只是字符串类型的数据。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 列中的唯一数字。

我想象在 for 或 while 循环中运行 if/else 语句,检查“D”中的每个单元格,并将以前未“看到”的任何值存储在数组中。然后在 E 列中输出数组。

我想知道是否有更有效的方法来做到这一点。以上只是一个小例子。数据范围很可能在 400 范围内。(按行。列只有 4 或 5 列,包括新的输出列。)

提前致谢。

PS我在这里搜索了这个,但我只收到与删除重复行相关的问题。如果有一个问题已经问这个问题,请给我链接。

4

4 回答 4

18

您可以使用该功能在google-spreadsheetsUNIQUE中执行此操作。
这是所有可用功能的文档
(您可以UNIQUEFilter类别中找到)

您很可能希望插入到单元格中E1

=UNIQUE(D1:D)

E这将使用来自所有列的唯一值填充列,D同时保留顺序。此外,这将动态更新并反映对 column 所做的所有更改D

要在google-apps-script中做到这一点:

SpreadsheetApp.getActiveSheet()
 .getRange("E1").setFormula("=UNIQUE(D1:D)");
于 2013-06-30T21:55:10.310 回答
7

这是一种方法......可能不是唯一的,但可能还不错......

我添加了一些日志以在记录器中查看中间结果。

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))
  }

编辑 :

按照 Theodros 的回答,电子表格公式确实是一个优雅的解决方案,我从没想过,但我应该!;-)

=SORT(UNIQUE(D1:D))

给出完全相同的结果......

于 2013-06-28T20:52:44.620 回答
2

目前,在 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);
};
于 2020-10-08T17:04:59.620 回答
1

这是一个脚本,用于获取列中非空值的唯一列表,给定它所在的工作表和列的标题位置,使用数组存储值和 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;
}
于 2020-10-08T16:20:39.333 回答