Subsref with cells

那年仲夏 提交于 2019-12-21 17:53:41

问题


This issue appeared when I was answering this question. It should be some stupid error I am doing, but I can't get what error it is…

myMatrix = [22 33; 44 55]

Returns:

>> subsref(myMatrix, struct('type','()','subs',{{[1 2]}} ) );    

ans =

    22    44

While using it with cells:

myCell = {2 3; 4 5} 

Returns:

>> subsref(myCell,struct('type','{}','subs',{{[1 2]}} ) );

ans =

     2  % WHATTT?? Shouldn't this be 2 and 4 Matlab??

Checking the subsref documentation, we see:

See how MATLAB calls subsref for the expression:

A{1:2} The syntax A{1:2} calls B = subsref(A,S) where S.type='{}' and S.subs={[1 2]}.

This seems not to be true because the returned value by subsref is just the first argument, not all arguments.

Then if one does:

>> [a,b]=subsref(myCell,struct('type','{}','subs',{{[1 2]}} ) ) 

a =

     2


b =

     4 % Surprise!

But this is not the same as myCell{[2 4]} which will automatically return:

>> myCell{[1 2]}                                               

ans =

     2


ans =

     4

I would need to use subsref with one output for every index I use access myCell, or am I missing something?


回答1:


When the curly braces ({}) are used for indexing a cell array, the output is a comma-separated list. This implicitly calls subsref but the behavior is slightly different from invoking it directly.

subsref by itself is a technically a function, and the comma-separated list returned by the curly braces simply behaves like varargout in this case. This means that you should specify an appropriate "sink" for all desired output results, just like you would do with any other function returning multiple parameters, otherwise they would be ignored.




回答2:


dont ask me why, this is just something I tried:

myOutput=subsref(myCell,struct('type','()','subs',{{[1 2]}} ) )

note the 'type','()'!

this gives me:

myOutput = 

[2]    [4]

with myOutput as cell. Converting back:

>> myOutput=cell2mat(subsref(myCell,struct('type','()','subs',{{[1 2]}})))

myOutput =

 2     4

This is just a "fast" answer, that will need some improvements or some background-info as well...




回答3:


I was further investigating @EitanH answer and managed to find more details.

Yeah, it returns a comma separed list, but the function subsref should return a comma separed list just the A{:} does. Here is an example where the functions behave different, but this is an expected behavior, I would like the class .get method to return a list and one class common function to behave as common functions getting only the first argument from the cell.

classdef ListReturn

  properties(Access = private)
    a
  end

  properties(Dependent)
    getA
  end

  methods
    function self = ListReturn(a)
      self.a = a;
    end
    function varargout = get.getA(self)
      varargout = {self.a};
    end
    function varargout = getAFcn(self)
      varargout = {self.a};
    end
  end
end

There is a substantial difference when calling the functions, exactly as the .get:

k=[ListReturn(2) ListReturn(3) ListReturn(4) ListReturn(5)]
>> k.getAFcn

ans =

     2

>> k.getA

ans =

     2


ans =

     3


ans =

     4


ans =

     5

So it seems that using A{1:2} or A{:} works like a Cell.get(), whereas the subsref works as a common matlab function, returning only one argument when the output arguments are not specified, as one function in C,java,C++ would do. Anyway, I just feel like subsref should work as the .get.



来源:https://stackoverflow.com/questions/18384735/subsref-with-cells

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!