我在GUI中(使用GUIDE)构建了一个便于使用的(4x5),最后一行符合逻辑,因此我可以选择要删除的行。
d = {'L1',1,10,true;'L2',2,20,true;'L3',3,30,false;'L4',4,40,true;'L4',5,50,false};
set(handles.outputTable,'Data',d)
我创建了一个按钮来删除选定的行,但是我不起作用:
function deleteButton_Callback(hObject, eventdata, handles)
% hObject handle to deleteButton (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
dataTable = (get(handles.outputTable,'data'));
[m n] = size(dataTable);
disp(dataTable);
for i = 1:m
if num2str(cell2mat(dataTable(i,4))) =='1'
dataTable(i,:)=[];
end
end
disp('Modifed table')
disp(dataTable);
如何解决它,以便在GUI中重新设置表?
答案 0 :(得分:1)
这是错误的:
for i = 1:m
if num2str(cell2mat(dataTable(i,4))) =='1'
dataTable(i,:)=[];
end
end
首先,if num2str(cell2mat(dataTable(i,4))) =='1'
是if dataTable{i,4}==1
的复杂部分。您应该学习使用花括号{}
来访问单元格数组的内容。
然后,仅当计数器减少时它才起作用。 看看会发生什么:
Test if row n should be deleted
Delete line n; the content of row (n+1) have now moved to row n
Increment counter i from value n to n+1
The row now at position n has never been tested for deletion !
从不测试行(n + 1)上的内容,因为删除操作首先将其向后移动,然后计数器递增而无需再次测试。解决方案是减少计数器。
for i = m:-1:1
if dataTable{i,4}
dataTable(i,:)=[];
end
end
通过删除操作移动的行已经过测试,因此最后可以确定所有行都已经过测试。
现在,只需一行就可以矢量化形式获得相同的结果
dataTable = dataTable(cell2mat(dataTable(:,4))==0,:);
整个功能归结为:
function deleteButton_Callback(hObject, eventdata, handles)
dataTable = get(handles.outputTable,'data');
% Do some checks to make sure that the values input by are correct %
assert(all(cellfun(@isscalar,dataTable(:,4))), 'Last colum should contain scalars!');
set(handles.outputTable,'data' , dataTable(cell2mat(dataTable(:,4))==0,:));
end