 # Extracting "one row" from a cell array of objects

As I delve further into object-oriented Octave, I’ve been replacing data structures for which I had previously been using a matrix (wherein each column is one record, and the matrix grows to the right as I add new records) with cell arrays of objects (where each object is an entire record, and the cell array has only a single row).

I’m using the word “record” here just to mean any data structure that I was previously representing as a column vector. For example, a pure sinusoidal tone can be represented by three real numbers, namely its frequency, amplitude, and initial phase; thus, when I wanted an array of sinusoids, I would use a matrix with three rows. Each sinusoid would be represented by a 3-element column vector.

In my new object-oriented approoach, each sinusoid is represented by an object with three properties, and if I want an array of them, I use a cell array of sinusoid objects.

With all of that in mind, I present to you my new function `cellExtract`, which extracts one “row” from a cell array of objects:

``````## a is a cell array of objects
## f is a string which is the name of a property or a method

## returns a vector consisting of the values of a{:}.f

function out = cellExtract(a, f)
out = cellfun(@(o) subsref(o, struct ("type", ".", "subs", f)), a);
endfunction
``````

So, in my example above, if `tones` is a cell array of objects, and each object has properties `freq`, `ampl`, and `phase`, then `cellExtract(tones, "freq")` returns an array of the `freq` values.

If I want to sort `tones` by frequency, I can go

``````[~, order] = sort(cellExtract(tones, "freq"));
tones = tones(order);
``````

I haven’t yet figured out how to perform the sort in one line without resorting to a temporary variable.

I would love your feedback please on all of the above. Is it useful? Should I name it something different? Is it unnecessary because there’s a simpler way without having to write a function? Is there a way to achieve this without breaking the abstraction barrier?

Thanks!

I’ve tested this with both properties and methods. Here’s a test class:

``````classdef TestClass

properties
a = 0
b = 0
endproperties

methods
function obj = TestClass(a,b)
obj.a = a;
obj.b = b;
endfunction

function x = m(obj)
x = obj.a + obj.b;
endfunction
endmethods

endclassdef
``````

And here’s a sample interaction:

``````>> objs = { TestClass(1,2) TestClass(4,5) TestClass(-1,5) };
>> cellExtract(objs, "a")
ans =

1   4  -1

>> cellExtract(objs, "m")
ans =

3   9   4

>>
``````

I think it might also work with a cell array of structs, but I haven’t tried that.