From 9aec0699ada10d62a55ff8ec7dca457387349363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=9F=83=E5=8D=9A=E6=8B=89=E9=85=B1?= Date: Mon, 29 May 2023 10:34:05 +0800 Subject: [PATCH] =?UTF-8?q?DataTypes.NDTable=EF=BC=9Abug=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=92=8C=E6=96=87=E6=A1=A3=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- +MATLAB/+DataTypes/NDTable.m | 220 +++++++++++++++++++++++++++--- README.md | 3 + resources/functionSignatures.json | 45 +++++- 3 files changed, 247 insertions(+), 21 deletions(-) diff --git a/+MATLAB/+DataTypes/NDTable.m b/+MATLAB/+DataTypes/NDTable.m index c2066a1..5388de2 100644 --- a/+MATLAB/+DataTypes/NDTable.m +++ b/+MATLAB/+DataTypes/NDTable.m @@ -1,10 +1,150 @@ classdef NDTable=I - obj.Dimensions{I}=obj.Dimensions{I}(Index); + ValidIndexLogical=Index<=numel(obj.Dimensions{I}); + if any(ValidIndexLogical) + NewStrings=repmat(string(missing),1,find(ValidIndexLogical,1,'last')); + NewStrings(ValidIndexLogical)=obj.Dimensions{I}(Index(ValidIndexLogical)); + obj.Dimensions{I}=NewStrings; + else + obj.Dimensions{I}=strings(1,0); + end end end obj.Data=obj.Data(Indices{:}); @@ -60,9 +216,11 @@ Names=indexOp(1).Name; Indices=repmat({':'},1,ndims(obj.Data)); for I=1:numel(obj.Dimensions) - [Exist,Index]=ismember(Names,obj.Dimensions{I}); - if any(Exist) - Indices{I}=Index(Exist); + if ~isempty(obj.Dimensions{I}) + [Exist,Index]=ismember(Names,obj.Dimensions{I}); + if any(Exist) + Indices{I}=Index(Exist); + end end end obj=obj.Data(Indices{:}); @@ -75,7 +233,9 @@ %括号索引返回的还是NDTable,因此不允许级联赋值,没有意义 function obj = parenAssign(obj,indexOp,varargin) [obj,Indices]=obj.IndexToAssign(indexOp); - obj.Data(Indices{:})=varargin{1}.Data; + NewObj=varargin{1}; + obj.Data(Indices{:})=NewObj.Data; + obj.DimensionNames(1:numel(NewObj.DimensionNames))=NewObj.DimensionNames; end function obj = braceAssign(obj,indexOp,varargin) [obj,Indices]=obj.IndexToAssign(indexOp(1)); @@ -88,13 +248,15 @@ function obj=dotAssign(obj,indexOp,varargin) Names=indexOp(1).Name; Indices=repmat({':'},1,ndims(obj.Data)); - AnyExist=false(numel(Name),1); + AnyExist=false(numel(Names),1); for I=1:numel(obj.Dimensions) - [Exist,Index]=ismember(Names,obj.Dimensions{I}); - if any(Exist) - Indices{I}=Index(Exist); + if ~isempty(obj.Dimensions{I}) + [Exist,Index]=ismember(Names,obj.Dimensions{I}); + if any(Exist) + Indices{I}=Index(Exist); + end + AnyExist=AnyExist|Exist; end - AnyExist=AnyExist|Exist; end Names=Names(~AnyExist); NumNewFields=numel(Names); @@ -114,13 +276,6 @@ obj.Data(Indices{:}).(indexOp(2:end))=varargin{:}; end end - function n=CommonListLength(obj,indexOp,Context) - if isscalar(indexOp) - n=1; - else - n=listLength(obj.(indexOp(1)),indexOp(2:end),Context); - end - end function n = parenListLength(obj,indexOp,Context) n=obj.CommonListLength(indexOp,Context); end @@ -162,6 +317,35 @@ end methods function obj=NDTable(Data,Dimensions,DimensionNames) + %从原始数据新建NDTable + %# 语法 + % ``` + % import MATLAB.DataTypes.NDTable + % + % obj=NDTable(Data); + % %用指定的多维数组构造NDTable + % + % obj=NDTable(Data,Dimensions); + % %额外指定各维度可用的字符串索引 + % + % obj=NDTable(Data,Dimensions,DimensionNames); + % %额外指定各维度的名称 + % ``` + %# 示例 + % ``` + % Data=rand(4,5,6,7); + % Dimensions={["A","B","C","D"];["E","F","G","H","I"];[];["M","N","O","P"]}; + % obj=MATLAB.DataTypes.NDTable(Data,Dimensions); + % ``` + % 上述代码创建了一个4维表,其中1、2、4维允许用字符串索引,第3维未指定字符串索引因此只能用数值索引。第4维长度为7但仅指定了前4个字符串索引,要访问后面的位置 + % 仍只能用数值索引。可以看到,必须在Dimensions中指定允许的字符串索引才能在该维度使用字符串索引,但无论是否指定,或不完全指定,永远可以用数值索引。具体索 + % 引语法见NDTable类文档。 + %# 输入参数 + % Data,填充NDTable的原始数据,可以是任意维度的数组。 + % Dimensions(:,1)cell=cell(0,1),各维各位置允许使用的字符串索引,每个元胞一个维度,元胞内是索引该维度各个位置的字符串。可以不指定或仅指定一部分,未指定的 + % 部分将只能用数值索引。 + % DimensionNames(:,1)string=strings(0,1),各维度名称。此参数对索引操作无实际用途,主要供人类阅读。 + %See also MATLAB.DataTypes.NDTable arguments Data Dimensions=cell(0,1) diff --git a/README.md b/README.md index f90a0a0..4d054fd 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,9 @@ end classdef EventLogger %事件记录器,类似于秒表 end +classdef NDTable + %N维表格,相当于支持字符串索引的N维数组 +end ``` 函数 ```MATLAB diff --git a/resources/functionSignatures.json b/resources/functionSignatures.json index 828e52c..b4a3095 100644 --- a/resources/functionSignatures.json +++ b/resources/functionSignatures.json @@ -736,6 +736,39 @@ } ] }, + "MATLAB.DataTypes.NDTable": { + "inputs": [ + { + "name": "Data", + "kind": "required", + "purpose": "填充NDTable的原始数据" + }, + { + "name": "Dimensions", + "kind": "ordered", + "type": [ + "cell", + "column" + ], + "purpose": "各维各位置允许使用的字符串索引" + }, + { + "name": "DimensionNames", + "kind": "ordered", + "type": [ + [ + "string", + "column" + ], + [ + "cell", + "column" + ] + ], + "purpose": "各维度名称" + } + ] + }, "MATLAB.DataTypes.RepeatingFun": { "inputs": [ { @@ -2706,7 +2739,7 @@ "name": "obj" }, { - "mutuallyExclusiveGroup":[ + "mutuallyExclusiveGroup": [ [ { "name": "Message", @@ -2726,7 +2759,10 @@ { "name": "BackTrace", "kind": "ordered", - "type":["logical","scalar"], + "type": [ + "logical", + "scalar" + ], "purpose": "是否显示堆栈跟踪" } ], @@ -2734,7 +2770,10 @@ { "name": "BackTrace", "kind": "ordered", - "type":["logical","scalar"], + "type": [ + "logical", + "scalar" + ], "purpose": "是否显示堆栈跟踪" }, {