Generate combinations of Cells that contain text
Afficher commentaires plus anciens
Hi there,
I am trying to generate all the combinations of certain cells so that each combination will include only one element of each vector/category. For example:
A = {'Square'; 'Rectangle'}
B = {'Heavy'; 'Light'; 'Medium'}
C = {'West'; 'East', 'South'; 'North'}
For output, I want a matrix that will have the following structure:
D = { 'Square-Heavy-West'; 'Square-Heavy-East' etc.}
If this would be possible without using cells, I would appreciate your thoughts.
Thank you in advance,
Andreas
5 commentaires
Bob Thompson
le 4 Avr 2018
You could give each word a number code and then have each row of the output simply be a series of numbers.
Andreas Georgakakos
le 4 Avr 2018
Bob Thompson
le 4 Avr 2018
You can make a series of string variables, but I don't believe it is possible to make an array of strings without doing cells, structures, or a table. Since you're looking to mix and match a group of already existing strings cells seem to be your best choice.
Why are you trying to avoid cells?
Andreas Georgakakos
le 4 Avr 2018
Stephen23
le 21 Mai 2019
"...but I don't believe it is possible to make an array of strings without doing cells, structures, or a table"
String arrays were introduced in R2016b. These are by definition an array of strings.
Réponses (3)
>> [Cx,Bx,Ax] = ndgrid(1:numel(C),1:numel(B),1:numel(A));
>> D = strcat(A(Ax(:)),'-',B(Bx(:)),'-',C(Cx(:)))
D =
'Square-Heavy-West'
'Square-Heavy-East'
'Square-Heavy-South'
'Square-Heavy-North'
'Square-Light-West'
'Square-Light-East'
'Square-Light-South'
'Square-Light-North'
'Square-Medium-West'
'Square-Medium-East'
'Square-Medium-South'
'Square-Medium-North'
'Rectangle-Heavy-West'
'Rectangle-Heavy-East'
'Rectangle-Heavy-South'
'Rectangle-Heavy-North'
'Rectangle-Light-West'
'Rectangle-Light-East'
'Rectangle-Light-South'
'Rectangle-Light-North'
'Rectangle-Medium-West'
'Rectangle-Medium-East'
'Rectangle-Medium-South'
'Rectangle-Medium-North'
"If this would be possible without using cells, I would appreciate your thoughts."
You could use string arrays, but the methods to generate all combinations would be exactly the same.
4 commentaires
Jos (10584)
le 21 Mai 2019
As a side note you can use ndgrid direclty on the cell arrays
[Cc, Bc, Aa] = ndgrid(C, B, A);
D = strcat(Aa(:), '-', Bb(:), '-', Cc(:))
Guillaume
le 21 Mai 2019
As a side note you can use ndgrid direclty on the cell arrays
As I've discovered recently because one of my Answer didn't work for somebody on R2016a,
- it's a fairly recent modification (of the full function on which ndgrid depends)
- it's not documented, so use at your own peril.
It's very handy though, so this reminds me to raise a bug report to ask it to be documented (together with strfind working on numeric arrays).
Rik
le 24 Mai 2019
RE: strfind, that is one of the examples where Octave sticks to the documented behavior, as it throws an error on numeric input. I know this question is not related to Octave, but I just wanted to put it out there.
Guillaume
le 24 Mai 2019
I've always felt a bit ambivalent about the fact that strfind can find sequences in numeric arrays. It is very handy (and you'll find it suggested every now and then on Answers) but a function with such a name shouldn't deal with numbers.
The best thing would be to either change the name (FindSequence) or simply duplicate the function with a new name that clearly applies to numerics.
Fabian Torres
le 21 Mai 2019
This worked for me but I am not sure about how fast can it be compared with the loop, but still more elegant:
A = {'Square'; 'Rectangle'}; nA = size(A, 1);
B = {'Heavy'; 'Light'; 'Medium'}; nB = size(B, 1);
C = {'West'; 'East'; 'South'; 'North'}; nC = size(C, 1);
D = reshape(strcat(repmat(B, 1, nC), '-', repmat(C', nB, 1))', [], 1);
nD = size(D, 1);
D = reshape(strcat(repmat(A, 1, nD), '-', repmat(D', nA, 1))', [], 1);
Bob Thompson
le 4 Avr 2018
If somebody knows a way to conduct this without loops feel free to mention it, but I do know that you can record all possible combinations using a set of for loops. Indexing can be a pain though if you just want a series of rows. Easier to look at as an output, just tricky to code.
lenA = size(A,1);
lenB = size(B,1);
lenC = size(C,1);
for first = 1:lenA; % Loop through first matrix
for second = 1:lenB; % Loop through second matrix
for third = 1:lenC; % Loop through third matrix
D{(first-1)*lenB*lenC+(second-1)*lenC+third,1} = A{first}; % Record word from first
D{(first-1)*lenB*lenC+(second-1)*lenC+third,2} = B{second}; % Record word from second
D{(first-1)*lenB*lenC+(second-1)*lenC+third,3} = C{third}; % Record word from third
% End single combination
end
end
end
Catégories
En savoir plus sur Data Type Conversion dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!