Spencer、Max 和Oliver 的答案都使用电子表格公式返回过滤后的数组。它们的优点是可以在将新行添加到源数据时自动重新计算。
但是,您专门询问了有关删除行的问题,而这些答案都没有。为此,您必须使用脚本,因为公式不会从电子表格中删除源数据。
这个 sn-p 包含一个完整的脚本,包括一个菜单驱动的用户界面,它将为当前工作表调用 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" ]
然后,我们可以在行数组的slices 上使用 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;
}