gusucode.com > datatypes 工具箱matlab源码程序 > datatypes/@tabular/subsrefDot.m
function [b,varargout] = subsrefDot(t,s) %SUBSREFDOT Subscripted reference for a table. % Copyright 2012-2016 The MathWorks, Inc. import matlab.internal.datatypes.isCharString import matlab.internal.tableUtils.isScalarInt % '.' is a reference to a table variable or property. Any sort of % subscripting may follow. Row labels for cascaded () or {} subscripting on % a variable are inherited from the table. if ~isstruct(s), s = struct('type','.','subs',s); end % Translate variable (column) name into an index. Avoid overhead of % t.varDim.subs2inds in this simple case. varName = s(1).subs; if isnumeric(varName) % Allow t.(i) where i is an integer varIndex = varName; if ~isScalarInt(varIndex,1) error(message('MATLAB:table:IllegalVarIndex')); elseif varIndex > t.varDim.length error(message('MATLAB:table:VarIndexOutOfRange')); end elseif ischar(varName) && (isrow(varName) || isequal(varName,'')) % isCharString(varName) varIndex = find(strcmp(varName,t.varDim.labels)); if isempty(varIndex) % If there's no such var, it may be a reference to the 'Properties' % (virtual) property. Handle those, but disallow references to % any property directly. Check this first as a failsafe against % shadowing .Properties by a dimension name. if strcmp(varName,'Properties') if isscalar(s) if nargout < 2 b = getProperties(t); else nargoutchk(0,1); end else % If there's cascaded subscripting into the property, let the % property's subsref handle the reference. This may result in % a comma-separated list, so ask for and assign to as many % outputs as we're given. That is the number of outputs on % the LHS of the original expression, or if there was no LHS, % it comes from numArgumentsFromSubscript. try if nargout < 2 b = getProperty(t,s(2:end)); else [b,varargout{1:nargout-1}] = getProperty(t,s(2:end)); end catch ME if strcmp(ME.identifier,'MATLAB:table:UnknownProperty') propName = s(2).subs; match = find(strcmpi(propName,t.propertyNames),1); if ~isempty(match) % a property name, but with wrong case match = t.propertyNames{match}; error(message('MATLAB:table:UnknownPropertyCase',propName,match)); else throw(ME); end else throw(ME); end end end return elseif strcmp(varName,t.metaDim.labels{1}) % If it's the row dimension name, return the row labels varIndex = 0; elseif strcmp(varName,t.metaDim.labels{2}) % If it's the vars dimension name, return t{:,:}. Deeper subscripting % is not supported, use explicit braces for that. if ~isscalar(s) error(message('MATLAB:table:NestedSubscriptingWithDotVariables',t.metaDim.labels{2})); end varIndex = -1; elseif strcmpi(varName,'Properties') % .Properties, but with wrong case error(message('MATLAB:table:UnrecognizedVarNamePropertiesCase',varName)); else match = find(strcmpi(varName,t.propertyNames),1); if ~isempty(match) match = t.propertyNames{match}; if strcmp(varName,match) % a valid property name error(message('MATLAB:table:IllegalPropertyReference',varName,varName)); else % a property name, but with wrong case error(message('MATLAB:table:IllegalPropertyReferenceCase',varName,match,match)); end else match = find(strcmpi(varName,t.varDim.labels),1); if ~isempty(match) % an existing variable name match = t.varDim.labels{match}; error(message('MATLAB:table:UnrecognizedVarNameCase',varName,match)); elseif ~isempty(find(strcmp(varName,t.defaultDimNames{1}),1)) % trying to access row labels by default name t.throwSubclassSpecificError('RowDimNameNondefault',varName, t.metaDim.labels{1}) else methodList = methods(t); match = find(strcmpi(varName,methodList),1); if ~isempty(match) % a method name match = methodList{match}; error(message('MATLAB:table:IllegalDotMethod',varName,match,match)); else % no obvious match error(message('MATLAB:table:UnrecognizedVarName',varName)); end end end end end else error(message('MATLAB:table:IllegalVarSubscript')); end if varIndex > 0 b = t.data{varIndex}; elseif varIndex == 0 b = t.rowDim.labels; else % varIndex == -1 b = extractData(t,1:t.varDim.length); end if isscalar(s) % If there's no additional subscripting, return the table variable. if nargout > 1 nargoutchk(0,1); end else s2 = s(2); if ~isequal(s2.type,'.') % t.Var(...) or t.Var{...} rowIndices = s2.subs{1}; if isnumeric(rowIndices) || islogical(rowIndices) || iscolon(rowIndices) % Can leave these alone to save overhead of calling subs2inds else % Dot-parens or dot-braces subscripting might use row labels inherited from the % table, translate those to indices. if ~iscolumn(b) && isscalar(s2.subs) error(message('MATLAB:table:InvalidLinearIndexing')); end numericRowIndices = t.rowDim.subs2inds(rowIndices); % subs2inds returns the indices as a col vector, but subscripting on % a table variable (as opposed to on a table) should follow the usual % reshaping rules. Nothing to do for one (char) name, including ':', but % preserve a cellstr subscript's original shape. if iscell(rowIndices), numericRowIndices = reshape(numericRowIndices,size(rowIndices)); end s(2).subs{1} = numericRowIndices; s2 = s(2); % update the local copy end else % A reference to a property or field, so no row labels end % Now let the variable's subsref handle the remaining subscripts in things % like t.name(...) or t.name{...} or t.name.property. This may return a % comma-separated list, so ask for and assign to as many outputs as we're % given. That is the number of outputs on the LHS of the original expression, % or if there was no LHS, it comes from numArgumentsFromSubscript. if length(s) == 2 try %#ok<ALIGN> if nargout < 2 b = subsref(b,s2); else [b,varargout{1:nargout-1}] = subsref(b,s2); end catch ME, throw(ME); end else % length(s) > 2 % Trick the third and higher levels of subscripting in things like % t.Var{i}(...) etc. into dispatching to the right place when % t.Var{i}, or something further down the chain, is itself a table. try %#ok<ALIGN> if nargout < 2 b = matlab.internal.table.subsrefRecurser(b,s(2:end)); else [b,varargout{1:nargout-1}] = matlab.internal.table.subsrefRecurser(b,s(2:end)); end catch ME, rethrow(ME); end % point to the line in subsrefRecurser end end