繁体   English   中英

忽略单元格的顺序,删除Google表格中的重复行

[英]Remove duplicated rows in Google Sheets ignoring the order of cells

我有一个包含许多“重复”行的电子表格。 我不想手动删除它们,因为我有数千行。 在我的特定情况下,行可能不是完全重复的 ,因为我不在乎行中单元格的顺序。 这是一个例子:

A   B
dog cat
apple orange
red blue
cat dog

在我的情况下, cat dog dog catcat 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的唯一列表,然后对原始表进行查询以获取实际的行。

SpencerMaxOliver的答案都使用电子表格公式来返回过滤后的数组。 它们的优点是,当将新行添加到源数据时,它们可以自动重新计算。

但是,您专门询问了有关删除行的问题,这些答案都没有。 为此,您必须使用脚本,因为公式不会从电子表格中删除源数据。

该片段包含一个完整的脚本,包括一个菜单驱动的用户界面,该界面将为当前工作表调用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM