我有一个包含许多“重复”行的电子表格。我不想手动删除它们,因为我有成千上万的行。在我的特定情况下,这些行可能不是完全重复的,因为我不在乎这些行中单元格的顺序。这是一个例子:
A B
dog cat
apple orange
red blue
cat dog
dog cat
并且cat dog
在我的情况下是重复的。因此,我想保留其中之一。不在乎哪个可能是第一个或最后一个。
我知道我需要某种与顺序无关的行比较。如何使用电子表格公式或Google Apps脚本完成此操作?
PS我的实际数据有7列,而我的示例没有2列。(从A到G)
Spencer,Max和Oliver的答案都使用电子表格公式来返回过滤后的数组。它们的优点是,当将新行添加到源数据时,它们可以自动重新计算。
但是,您专门询问了有关删除行的问题,这些答案都没有。为此,您必须使用脚本,因为公式不会从电子表格中删除源数据。
该代码段包含一个完整的脚本,包括一个菜单驱动的用户界面,该界面将调用delSimilarRows()
当前工作表的功能。它被编写为包含电子表格的脚本,但可以轻松转换为附件。
/**
* @OnlyCurrentDoc Limits the script to only accessing the current spreadsheet.
*/
/**
* Adds a custom menu
*
* @param {Object} e The event parameter for a simple onOpen trigger.
*/
function onOpen(e) {
SpreadsheetApp.getUi()
.createMenu('Custom')
.addItem('Delete similar rows', 'delSimRowsGUI')
.addToUi();
}
/**
* Prompt user for confirmation before proceeding with deletion.
* Provide results after operation.
*
*/
function delSimRowsGUI() {
var ui = SpreadsheetApp.getUi();
var choice = ui.alert("Confirm action",
"This will delete rows in the current sheet that contain sets of cells that already appear together in other rows.",
ui.ButtonSet.OK_CANCEL);
if (choice === ui.Button.OK) {
var numDeleted = delSimilarRows();
ui.alert("Deleted "+numDeleted+" row"+(numDeleted===1?'.':'s.'));
}
}
/**
* Delete rows in the current sheet that contain sets of cells that already
* appear together in other rows. (Almost duplicates, but order-independent.)
* From: https://stackoverflow.com/a/37304191/1677912
*
* @returns {Number} The number of matching rows that were deleted.
*/
function delSimilarRows() {
// Get all rows from sheet.
var currentSheet = SpreadsheetApp.getActiveSheet();
var data = currentSheet.getDataRange().getValues();
var numDeleted = 0;
// Sort cells within rows, and join into a string with (hopefully!) unique delimiter
var sorted = data.map(function(row) {
return row.sort().join(' |-| ');
});
// Identify duplicate rows in the sorted data, and delete the corresponding
// spreadsheet rows. (Note: looping backwards, so deletion is clean.)
for (var row=sorted.length-1; row>=0; row--) {
if (sorted.slice(0,row).indexOf(sorted[row]) !== -1) {
currentSheet.deleteRow(row+1);
numDeleted++;
}
}
return numDeleted;
}
完成所有实际工作的功能是delSimilarRows()
。它使用一些JavaScript魔术来识别要删除的行,并将其直接从当前工作表中删除。
它通过将行临时转换为它们的字符串表示形式来处理所有类型的数据,并按字母顺序对单元格内容进行排序,并在它们之间(希望)使用唯一的分隔符。这样做,您的示例数据将显示为(仅在计算机上),如下所示:
[ "cat |-| dog",
"apple |-| orange",
"blue |-| red",
"cat |-| dog" ]
然后,我们可以遍历行检查使用JavaScript重复Array.indexOf()
上法片的排阵不包括我们当前行的。
由于我们要处理的是基于0的JavaScript数组以及基于1的电子表格行,因此1
在索引一个或另一个时要加或减时要格外小心。
/**
* Delete rows in the current sheet that contain sets of cells that already
* appear together in other rows. (Almost duplicates, but order-independent.)
* From: https://stackoverflow.com/a/37304191/1677912
*
* @returns {Number} The number of matching rows that were deleted.
*/
function delSimilarRows() {
// Get all rows from sheet.
var currentSheet = SpreadsheetApp.getActiveSheet();
var data = currentSheet.getDataRange().getValues();
var numDeleted = 0;
// Sort cells within rows, and join into a string with (hopefully!) unique delimiter
var sorted = data.map(function(row) {
return row.sort().join(' |-| ');
});
// Identify duplicate rows in the sorted data, and delete the corresponding
// spreadsheet rows. (Note: looping backwards, so deletion is clean.)
for (var row=sorted.length-1; row>=0; row--) {
if (sorted.slice(0,row).indexOf(sorted[row]) !== -1) {
currentSheet.deleteRow(row+1);
numDeleted++;
}
}
return numDeleted;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句