I am new to Excel. I have a spreadsheet containing 140 rows of 3 columns each, and trying to find the rows which share 2 of its columns with another row, and add the unique columns from each row to them. I can't seem to wrap my head around how to go about this.
For example:
Person 1 | Person 2 | Person 3 |
---|---|---|
Amy | Brian | CJ |
Amy | Brian | Dylan |
Amy | Dylan | Erica |
Brian | CJ | Dylan |
CJ | Erica | Fiona |
Dylan | Erica | Fiona |
Each row has its cells sorted alphabetically. I would like to be able to create a new table containing all possible 4 person groups.
Person 1 | Person 2 | Person 3 | Person 4 |
---|---|---|---|
Amy | Brian | CJ | Dylan |
Amy | Brian | Dylan | Erica |
Amy | Dylan | Erica | Fiona |
CJ | Dylan | Erica | Fiona |
Formula in E2
:
=LET(_data,A2:C7,TEXTSPLIT(TEXTAFTER(UNIQUE(BYROW(DROP(REDUCE(0,SEQUENCE(ROWS(_data)),LAMBDA(_main,_iter,LET(_index,INDEX(_data,_iter,),_4th,BYROW(FILTER(_data,BYROW(_data,LAMBDA(_row,SUM(COUNTIF(_index,_row))=2))),LAMBDA(_row,FILTER(_row,COUNTIF(_index,_row)=0))),IF(@ISERR(_4th),_main,VSTACK(_main,IF({1,0,0,0},_4th,HSTACK(0,_index))))))),1),LAMBDA(_row,TEXTJOIN(0,0,,SORT(_row,,,1))))),0,{1,2,3,4}),0))
If need be I can add some explanation.
------------------------------------
Edit: As per request, I'll add an explanation. Hopefully it helps.
Explanation:
I have used REDUCE()
as an accumulator, feeding it the amount of rows of the input data as the times we are iterating. In other words, the formula will repeat itself exactly the same times as there are rows with a growing end-result;
The 1st step inside this iterator is to seperate the current row. Meaning, I'm using the the iterator (I named it '_iter') to identify the row within the data look at within the current iteration. The result is stored in '_index' for later usage;
Now I'm creating a '_4th' variable, it's whole purpose is to find who can be a 4th person looking at the 3 from our '_index'. The technique; iterate rows! Our inner BYROW()
is there to check which rows hold exactly two values that are the same as the three from '_index'. I've used COUNTIF()
or this since we are still using ranges. The result: all rows that have exactly and only two out of three values in common with our '_index';
The outer BYROW()
is there to loop the result of the previous step. The FILTER()
applied here takes the single uncommon name out of each row. So here we end up with a vertical 1*n array of names;
Then we simply check if '_4th' holds an error or not. If not, we VSTACK()
the accumulated value with HSTACK()
'd output of the previous step (our 1*n array of singel names) with our '_index', the starting three names in the current iteration;
To top it all of we need to use one more BYROW()
to SORT()
each row in our accumulated end-result alphabetically and use TEXTJOIN()
just so we can use UNIQUE()
to have only unique combinations;
This is then finished of with a combination of TEXTSPLIT()
and TEXTAFTER()
to extract the 4 names out of these values into seperate columns.
I hope this made sense. Just in case, here is a very simplified visual (over two screenshots to make it fit) of the 6 iterations within the accumulator and what happens at the end outside the accumulator to arrive at the finale results.