我有这种形式的电子表格:
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列中的唯一数字。
我想象在for或while循环中运行if / else语句,它检查“D”中的每个单元格并存储以前未在数组中“看到”的任何值。然后在E列中输出数组。
我想知道是否有更有效的方法来做到这一点。以上只是一个小例子。最有可能的数据范围是400范围。 (行明智。列只有4或5,包括新的输出列。)
提前致谢。
P.S。 我在这里搜索了这个,但我只收到与删除重复行有关的问题。如果有问题已经提出,请与我联系。
答案 0 :(得分:14)
您可以使用UNIQUE
功能在 google-spreadsheets 内进行此操作。
Here is the doc to all available functions。
(您在UNIQUE
类别中找到Filter
)
您最有可能要插入单元格E1
:
=UNIQUE(D1:D)
这将使用所有列E
中的唯一值填充列D
,同时保留订单。此外,这将动态更新并反映对列D
所做的所有更改。
在 google-apps-script
中执行此操作SpreadsheetApp.getActiveSheet()
.getRange("E1").setFormula("=UNIQUE(D1:D)");
答案 1 :(得分:5)
这是一种方法来做到这一点......可能不是唯一一个但可能并不坏......
我添加了一些日志来查看记录器中的中间结果。
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))
给出完全相同的结果......
答案 2 :(得分: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;
}
或者,使用“位置”查找值:
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;
}
答案 3 :(得分:1)
当前,在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);
};