2012-05-24 2 views
2

У меня есть куча строк в электронной таблице Google, которые выглядят, как например:Создание списка уникальных пар из списка комбинаций многозначных в электронной таблице Google

a,b,c,d 
a,d 
c,d 
b,d,f 
a,b,f,g,h,i 
q,b,b 

... И далее.

Мне нужен способ, чтобы создать уникальный список связанных пар в этом формате:

a,b 
a,c 
a,d 
b,c 
b,d 
c,d 
b,f 
d,f 
a,f 
a,g 
a,h 
a,i 

... и дальше.

Любая идея, как я это сделаю? Я открыт для ответов с использованием языка сценариев Google Spreadsheet, языка сценариев Excel 2004 или чего-то еще, подобного PHP.

Спасибо!

+1

Возможно, вы захотите добавить в свой вышеуказанный вопрос, что используете Excel 2004? –

+0

Да, извиняюсь за это - я не понимал, что есть разница между двумя версиями. – aendrew

ответ

2

Не уверен, если это отвечает вашим требованиям платформы, но вот формула таблицы, которые могут быть использованы в себе электронные таблицы Google (не в любой версии Excel, хотя):

=ArrayFormula(SORT(TRANSPOSE(SPLIT(CONCATENATE(REPT(UNIQUE(TRANSPOSE(SPLIT(JOIN(",";A:A);",")))&","&TRANSPOSE(UNIQUE(TRANSPOSE(SPLIT(JOIN(",";A:A);","))));(UNIQUE(TRANSPOSE(SPLIT(JOIN(",";A:A);",")))<=TRANSPOSE(UNIQUE(TRANSPOSE(SPLIT(JOIN(",";A:A);",")))))*REGEXMATCH(CONCATENATE(","&SUBSTITUTE(A:A;",";",,")&","&CHAR(9));"(,"&UNIQUE(TRANSPOSE(SPLIT(JOIN(",";A:A);",")))&",[^\t]*,"&TRANSPOSE(UNIQUE(TRANSPOSE(SPLIT(JOIN(",";A:A);","))))&",)|(,"&TRANSPOSE(UNIQUE(TRANSPOSE(SPLIT(JOIN(",";A:A);","))))&",[^\t]*,"&UNIQUE(TRANSPOSE(SPLIT(JOIN(",";A:A);",")))&",)"))&CHAR(9));CHAR(9))))) 

Он также предполагает, что вы дон 't хотите перечислить "b, a", а также "a, b".

EDIT: Такие формулы могут быть ужасно неэффективными для очень больших наборов данных, поэтому рассмотрим только использование при обработке нескольких сотен строк или меньше.

+1

Вы построили эту формулу? Потому что это и поражает, и пугает меня. Серьезно блестящая работа - он заставляет Google Spreadsheets сдерживаться на 2 минуты с моим набором данных на 600 строк, но работает фантастично. – aendrew

+0

Выбор в качестве ответа, потому что он хорошо работает и его легко реализовать. – aendrew

+0

Возможно, я слишком скоро высказался - я удвоил свой набор данных, и он просто перестает работать ... – aendrew

1

Вот функция, чтобы пары:

<?php 
function make_pairs($str) { 
    $chars = explode(',', $str); 
    for ($i = 0; $i <= count($chars); $i++) { 
    $f = array_shift($chars); 
    foreach ($chars as $char) 
     echo "$f,$char\n"; 
    } 
} 

make_pairs('a,b,c,d'); 

Результат:

a,b 
a,c 
a,d 
b,c 
b,d 
c,d 
1

Так как вы отметили выше вопрос с VBA, вот решение VBA.

Это даст вам все 45 уникальных комбинаций, которые должен иметь ваш вышеприведенный пример.

Мои предположения

1) данные в Col А Лист1

2) Col A не имеет каких-либо заголовков

3) выход будет генерируется в Col B

4) Вы используете Excel 2007 +

5) Вы рассматриваете b,b как действительное сочетание из-за q,b,b. Если нет, тогда нужно добавить небольшую настройку.

Option Explicit 

Sub Sample() 
    Dim ws As Worksheet 
    Dim lRow As Long, nRow As Long, n As Long 
    Dim i As Long, j As Long, k As Long 
    Dim Myar() As String, TempAr() As String 

    Set ws = Sheet1 
    lRow = ws.Range("A" & Rows.count).End(xlUp).Row 

    n = 0: nRow = 1 

    With ws 
     For i = 1 To lRow 
      Myar = Split(.Range("A" & i).Value, ",") 
      If UBound(Myar) > 1 Then 
       For j = LBound(Myar) To UBound(Myar) 
        For k = LBound(Myar) To UBound(Myar) 
         If j <> k Then 
          ReDim Preserve TempAr(n) 
          TempAr(n) = Myar(j) & "," & Myar(k) 
          n = n + 1 
         End If 
        Next k 
       Next j 
      Else 
       ReDim Preserve TempAr(n) 
       TempAr(n) = .Range("A" & i).Value 
       n = n + 1 
      End If 
     Next i 

     For i = LBound(TempAr) To UBound(TempAr) 
      .Range("B" & nRow).Value = TempAr(i) 
      nRow = nRow + 1 
     Next i 

     '~~> Remove duplicates 
     .Range("$B$1:$B$" & UBound(TempAr) + 1).RemoveDuplicates _ 
     Columns:=1, Header:=xlNo 

     '~~> Sort data 
     .Range("$B$1:$B$" & UBound(TempAr) + 1).Sort _ 
     .Range("B1"), xlAscending 

     Debug.Print "Total Combinations : " & _ 
     Application.WorksheetFunction.CountA(Columns(2)) 
    End With 
End Sub 

enter image description here

Followup

Не уверен, если это будет работать с Excel 2004, но заменить строку

 .Range("$B$1:$B$" & UBound(TempAr) + 1).RemoveDuplicates _ 
     Columns:=1, Header:=xlNo 

с

 For i = 1 To UBound(TempAr) 
      If Application.WorksheetFunction.CountIf(.Range("B" & i).Value) > 1 Then 
       .Range("B" & i).ClearContents 
      End If 
     End With 

Отдых остается тем же, что и я. Проверьте это и сообщите мне, если вы получите какие-либо ошибки?

+0

Это выглядит потрясающе, но каким-либо образом вы можете сделать это совместимым с Excel 2004? Я нахожусь на Mac ... – aendrew

+0

Извините, у меня нет Excel 2004. У меня есть Excel 2011. Я считаю, и я мог ошибаться, но весь код должен оставаться таким же, как и '.Range (" $ B $ 1: $ B $ "& UBound (TempAr) + 1) .RemoveDuplicates _ Столбцы: = 1, Заголовок: = xlNo'. Вместо этого вам придется перебирать ячейки для удаления дубликатов. –

+0

Обновлено мое сообщение выше –

Смежные вопросы