gusucode.com > datatypes 工具箱matlab源码程序 > datatypes/@categorical/cat.m
function a = cat(dim,varargin) %CAT Concatenate categorical arrays. % C = CAT(DIM, A, B, ...) concatenates the categorical arrays A, B, ... % along dimension DIM. All inputs must have the same size except along % dimension DIM. Any of A, B, ... may also be a cell arrays of character % vectors or scalar strings. % % If all the input arrays are ordinal categorical arrays, they must have the % same sets of categories, including category order. If none of the input % arrays are ordinal, they need not have the same sets of categories. In this % case, C's categories are the union of the input array categories. However, % categorical arrays that are not ordinal but are protected may only be % concatenated with other arrays that have the same categories. % % See also HORZCAT, VERTCAT. % Copyright 2006-2016 The MathWorks, Inc. import matlab.internal.datatypes.isCharStrings % Start out the concatenation with the first array. Find the first % "real" categorical as a prototype for converting cell arrays of character % vectors. a = varargin{1}; if isa(a,'categorical') prototype = a; else % This is expensive if nargin is large, so only do it if necessary. prototype = varargin{find(cellfun(@(x)isa(x,'categorical'),varargin),1,'first')}; % The first array needs to be converted to categorical. if isequal(a,[]) a = prototype; a.codes = a.codes([]); % empty 'like' a.codes elseif isCharStrings(a) || (isstring(a) && isscalar(a)) a = strings2categorical(a,prototype); elseif iscell(a) error(message('MATLAB:categorical:cat:TypeMismatchCell')); else error(message('MATLAB:categorical:cat:TypeMismatch',class(a))); end end % The inputs must be all ordinal or not, so need only save one setting. isOrdinal = prototype.isOrdinal; for i = 2:nargin-1 b = varargin{i}; if isa(b,'categorical') if b.isOrdinal ~= isOrdinal error(message('MATLAB:categorical:OrdinalMismatchConcatenate')); end elseif isequal(b,[]) % Accept [] as a valid "identity element" for either arg. continue; % completely ignore this input else % ~isa(b,'categorical') if isCharStrings(b) || (isstring(b) && isscalar(b)) b = strings2categorical(b,prototype); elseif iscell(b) error(message('MATLAB:categorical:cat:TypeMismatchCell')); else error(message('MATLAB:categorical:cat:TypeMismatch',class(b))); end end if isequal(a.categoryNames,b.categoryNames) % If the categoryNames are identical, the internal codes are of the same class acodes = a.codes; bcodes = b.codes; elseif ~isOrdinal % Convert b to a's categories, possibly expanding the set of categories % if neither array is protected (bcodes & acodes will be casted to % an appropriate class to handle the expanded range). [bcodes,a.categoryNames] = convertCodes(b.codes,b.categoryNames,a.categoryNames,a.isProtected,b.isProtected); acodes = cast(a.codes, 'like', bcodes); % bcodes is always a higher or equivalent integer class as acodes else error(message('MATLAB:categorical:OrdinalCategoriesMismatch')); end a.isProtected = a.isProtected || b.isProtected; try acodes = cat(dim, acodes, bcodes); a.codes = acodes; % acodes and bcodes are the same correct type by now, don't need a cast catch ME throw(ME); end end