Combining cells so items occur randomly or pseudorandomly within a new array

2 vues (au cours des 30 derniers jours)
Alice
Alice le 13 Fév 2015
Modifié(e) : Alice le 16 Fév 2015
I have two arrays of different sizes, and I want to insert items from one array into the other array for a specified number of spaces whilst keeping the items in the first array in the same order (e.g prime1 then target1).
for example I have experimental order which is an 8x1 cell
expitemorder =
'Strong_Alt_Prime2.png'
'Strong_Alt_Target2.png'
'Strong_Alt_Prime1.png'
'Strong_Alt_Target1.png'
'Strong_Alt_Prime3.png'
'Strong_Alt_Target3.png'
'Strong_Alt_Prime4.png'
'Strong_Alt_Target7.png'
and I have filler order which is a 3x1 cell
fillitemorder =
'Ad Hoc Alt Prime3.png'
'Ad Hoc Alt Prime2.png'
'Ad Hoc Alt Prime1.png'
I would like to combine these such that I have a new cell which is 11x1 where fillitemorder has been randomly inserted at three spots in expitemorder. Or if not randomly then just at three spots in expitemorder (but not just vertically concatenated at the end).
Importantly though I need to keep the pairs of items in expitemorder together (e.g. I need prime2 and target2 together etc).
Any help would be greatly appreciated. Thanks!
  1 commentaire
Image Analyst
Image Analyst le 13 Fév 2015
Then why not have expitemorder be a two column cell array, with primes in teh first column and tarets in the second column? It would be so much easier to keep them together that way.

Connectez-vous pour commenter.

Réponses (1)

David Young
David Young le 13 Fév 2015
Modifié(e) : David Young le 13 Fév 2015
% test data
expitemorder = {
'Strong_Alt_Prime2.png'
'Strong_Alt_Target2.png'
'Strong_Alt_Prime1.png'
'Strong_Alt_Target1.png'
'Strong_Alt_Prime3.png'
'Strong_Alt_Target3.png'
'Strong_Alt_Prime4.png'
'Strong_Alt_Target7.png'
};
fillitemorder = {
'Ad Hoc Alt Prime3.png'
'Ad Hoc Alt Prime2.png'
'Ad Hoc Alt Prime1.png'
};
% code to combine arrays
Ne = length(expitemorder)/2; % no. experiments
Nf = length(fillitemorder);
N = Ne + Nf;
fpos = sort(randperm(N, Nf)); % fill positions
epos = find(~ismember(1:N, fpos)); % experiment positions
% insert data into output array
expFillItemOrder = cell(2*N, 1); % results, padded
expFillItemOrder (epos*2-1) = expitemorder(1:2:end);
expFillItemOrder (epos*2) = expitemorder(2:2:end);
expFillItemOrder (fpos*2-1) = fillitemorder;
expFillItemOrder (fpos*2) = []; % remove padding
Notes
  • If the order of the elements of fillitemorder is to be randomised, replace
fpos = sort(randperm(N, Nf));
with
fpos = randperm(N, Nf);
  • If you want the elements of fillitemorder always to be inserted between two elements of expitemorder, not at the beginning and end, replace the same line with
fpos = sort(randperm(N-2, Nf)+1);
  • If you want the elements of fillitemorder always to be separated by some elements of expitemorder, and not adjacent to each other in the output array, one possibility is to replace the same line with
while 1
fpos = sort(randperm(N-2, Nf)+1); % fill positions
if min(diff(fpos)) > 1; break; end
end
You can combine these modifications, but if the call to sort is omitted from the modification above you will need to change the test to
if min(diff(sort(fpos))) > 1; break; end
Also note that this last modification will not terminate unless expitemorder is long enough to allow the insertions to be separated. It may also be extremely slow if the lengths of the arrays are large and the filling is not sparse - if that is the case, please say as a better technique could be worked out.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by