[英]Remove duplicated rows in Google Sheets ignoring the order of cells
我有一個包含許多“重復”行的電子表格。 我不想手動刪除它們,因為我有數千行。 在我的特定情況下,行可能不是完全重復的 ,因為我不在乎行中單元格的順序。 這是一個例子:
A B
dog cat
apple orange
red blue
cat dog
在我的情況下, cat dog
dog cat
和cat dog
是重復的。 因此,我想保留其中之一。 不在乎哪個可能是第一個或最后一個。
我知道我需要某種與順序無關的行比較。 如何使用電子表格公式或Google Apps腳本完成此操作?
PS我的實際數據有7列,而我的示例沒有2列。 (從A到G)
我沒有使用Google表格的經驗,但是這里是我在Excel中所做的事情,希望您可以通過某種方式進行復制。
就像一條評論所暗示的那樣,使用“ Remove Duplicates
將按您的要求進行操作,但是首先您需要以一種能夠拾取這些重復項的方式對列表進行規范化。
在C列中: =IF(A1<B1,A1,B1)
在D列中: =IF(A1<B1,B1,A1)
這實際上將按字母順序將值放在A和B列的C和D列之間,然后您可以對這兩個新列執行Remove Duplicates
。
根據奧利弗·卡爾(Oliver Carr)提供的解決方案,這里是單配方解決方案:
=unique(arrayformula({IF(A:A<B:B,A:A,B:B),IF(A:A<B:B,B:B,A:A)}))
對於許多行甚至更多列的靈活解決方案,請嘗試以下操作:
假設您的數據位於第1行的A:G列中。
在H1中: =2^COUNTIF($A:$G,"<"&A1)
將此公式從H復制到N,並根據需要向下覆蓋任意行以覆蓋所有數據單元。
在O1中: =SUM($H:$N)
並將其復制下來以覆蓋所有行。
對於具有相同單詞的行,O中的值將相同。 現在,您可以刪除列O上的重復項。
您正在執行的操作是為數據中的每個單詞分配2的唯一冪,並且保證總和是唯一的(請考慮一個二進制數,該位數與唯一單詞的位數一樣多,如果該單詞將每個數字設置為1,出現在行中,否則為零)。
如果您想要一個更簡潔的版本,也可以將其輸入為數組公式(同樣以A:G中的數據):
在H1中: =SUM(2^COUNTIF(A:G,"<"&A1:G1))
通過按Cntl + Shift + Enter或在Google表格中輸入: =ArrayFormula(SUM(2^COUNTIF(A:C,"<"&A1:C1)))
如果您僅限使用Google表格,則可以在H上使用UNIQUE
函數來獲取ID的唯一列表,然后對原始表進行查詢以獲取實際的行。
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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.