0

If I have a 4x1 Cell structure with that represents a=[A1 A2 A3 A4] :

a=cell(4,1)
a{1}=[1 3 1 0]
a{2}=[3 3 3 3]
a{3}=[3 2 3 2]
a{4}=[3 3 3 2]

B=[1 1 1 2]; %priority

I would like to do the following :

Pick cells that correspond to priority B=[1 1 1 2] (where B=1 is highest priority and A=3)
Which means, find any cell that begins with [3 3 3 #], where all their priority is 1's in B.

ideal answer should be : a{2}=[3 3 3 3] and a{4} = [3,3,3,2]


My try is to add this :

[P arrayind]=min(B) % problem is that arrayind return index=1 only .. not all indices
if P==1
   arrayindex = 1:4 ; %look at each index of the array
   c = a(cellfun(@(x) ismember(x(arrayindex), 3), a));
end

However this gives me an error stating :

Error using cellfun
Non-scalar in Uniform output, at index 1, output 1.
Set 'UniformOutput' to false.

By adjusting the code to accommodate this error :

c = a(cellfun(@(x) ismember(x(arrayindex), 3), a,'UniformOutput',false));

I get this error :

Error using subsindex
Function 'subsindex' is not defined for values of class 'cell'.

And now I'm stuck at this point.

10
  • did you try to edit the cellfun line according to the error? that is cellfun(@(x) ... ,'UniformOutput', false); Commented Mar 22, 2013 at 17:46
  • @natan Yes, I should have mentioned that. Updating question Commented Mar 22, 2013 at 17:46
  • What value(s) are you expecting for c after running this code? Commented Mar 22, 2013 at 17:47
  • @wakjah I updated the question so it's clearer..The results should be a{2} and a{4} Commented Mar 22, 2013 at 18:05
  • @NLed try: [val ind] = max(cellfun(@(x) length(find(ismember(x(arrayindex), 3))), a)); b = a(ind);. This will give the cell array with the highest number of 3s. Commented Mar 22, 2013 at 18:05

1 Answer 1

1

This may not be an elegant answer, but it is effective:

%The input cell array.
a = cell(4,1);
a{1} = [1 3 1 0];
a{2} = [3 3 3 3];
a{3} = [3 2 3 2];
a{4} = [3 3 3 2];

%The input priority array.
B = [1 1 1 2];

%The output cell array: preallocated for efficiency.
c = cell(size(a));

j = 1;
for i = 1:size(a,1)
%For each i
    if(all(((cell2mat(a(i))==3)&(B==1))==(B==1)))
    %"cell2mat" converts the cell arrays into easily comparable number arrays.
    %"X==Y" for matrices of the same size, will give you a result matrix of the same size with 1 where the values are equal and 0 elsewhere.
    %Thus, "cell2mat(a(i))==3" would compare the number matrices represented by "a{i}" with "3".
    %"(cell2mat(a(i))==3)&(B==1)" would do a logical AND operation with "B==1", that is, "[1 1 1 0]".
    %In short, since you want whereever "a{i}" is 3 when "B" is 1, we want those "a{i}" where the comparison stated above is the same as "B==1".
    %If the result array is the same as "B=1", we get "[1 1 1 1]" as the result of the comparison "((cell2mat(a(i))==3)&(B==1))==(B==1)".
    %The function "all" checks whether the input to it is completely non-zero: here if we get a "[1 1 1 1]" "all" will give us 1, else 0.
        c{j} = a{i};
        %Insert result array into "c" when condition is satisfied.

        j = j + 1;
        %Increment the index of "c".
    end
end


c = c(1:j-1);
%Truncate unused rows of "c".

cell2mat(c)
%Displays the value of "c" as computed.
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you so much for answering. Can you please tell me how the code is working ? I would like to learn rather than just use the code blindly.
Sure thing. I'll add comments to the answer.
Out of curiosity, would this also work if I want to check for more values ?? For example, if B=2, then check for (2 or 3) rather than just 3. Do I only need to change
If you want it to work for both B=2 and B=3, replace B==1 with (B==1) | (B==2) or (B==1) + (B==2). This will make it treat 2 the same way it treats 3.
Yes. I'm off for now. If you have any more doubts, leave them as comments below; I'll check back here later.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.