1

For example, I create a class 'student'

classdef student

 properties
    name
    sex
    age
 end

 methods
    function obj = student(name,sex,age)
    obj.name = name;
    obj.sex = sex;
    obj.age = age;
 end
end

and then create some objects in an array 'school'

school(1)=student(A,'boy',19)
school(2)=student(B,'girl',18)
school(3)=student(C,'boy',20)
school(4)=student(D,'girl',19)

My question is how to find the index of the objects with certain properties in the array 'school'?

For example, if I want to find students with age 19, the result will be index [1,4]

If I want to find students with age 19 and sex 'boy', the result will be index [1]

Further question 1: how to find the row and colume index? The object with sex 'girl' and age 19 lies in row 1 colume 4.

Further question 2: if school is an cell array, how to solve above problems?

  • There are two typos in the code above: In the first block an "end" is missing. In second block A, B, C, and D, should be replaced by 'A', 'B', 'C', and 'D'. – user16372530 Aug 04 '22 at 18:34

2 Answers2

1

Seems kind of homework questions. However here are the answers:

% find students with age 19,
find (  [school(:).age] == 19 )

% find students with age 19 and sex 'boy', 
find (  [school(:).age] == 19 & strcmp( { school(:).sex }, 'boy'   ) )

% how to find the row and colume index? 
[row, col] = ind2sub( size(school), find (  [school(:).age] == 19 & strcmp( { school(:).sex }, 'girl'   ) ) )

Considering the last question, I would convert the cell of school objects back into an array and do as shown above.

user16372530
  • 692
  • 2
  • 13
  • Thank you very much! but in my program, I can't convert the cell to an array, because the elements of cell belongs to different subclass (although they share same parent class). It says"cell2mat(Agent) Error using cell2mat All contents of the input cell array must be of the same data type. ". Please visit this page , I can't create an array(I don't why),so I have to create a cell array to include objects with diffrent subclass. – TheAngryToad Aug 04 '22 at 05:23
  • If you request two outputs from `find` then it gives you the row and column indices, you do not need to go via `ind2sub` – Wolfie Aug 04 '22 at 07:08
  • That is correct for the example above as `school` is a row-vector. But considering the more general case that `school` could be a real 2D-matrix that would not work. Reason for this is, that it is unrolled to collect that data from the fields. – user16372530 Aug 04 '22 at 20:12
0

If school is a cell array so you have

school = cell(4,1);
school{1}=student(A,'boy',19)
school{2}=student(B,'girl',18)
school{3}=student(C,'boy',20)
school{4}=student(D,'girl',19)

Then you can loop through them to evaluate your conditions. A concise way to do this is with cellfun:

boolAge19 = cellfun( @(x) x.age == 19, school );
idxAge19  = find( boolAge19 );
boolBoy   = cellfun( @(x) strcmp( x.sex, 'boy' ), school );
idxBoy    = find( boolBoy );
boolBoyAnd19 = boolAge19 & boolBoy;
idxBoyAnd19  = find( boolBoyAnd19 );

You can of course skip intermediate steps, the lines just get dense

idxBoyAnd19 = find( cellfun( @(x) x.age == 19, school ) & ...
                    cellfun( @(x) strcmp( x.sex, 'boy' ), school ) );
Wolfie
  • 27,562
  • 7
  • 28
  • 55