assign the fields of a structure correctly

조회 수: 6 (최근 30일)
Luca Re
Luca Re 2024년 9월 8일
댓글: Luca Re 2024년 9월 10일
h, i want to add d1 to table
app.Preset_UITable.Data(end+1,:)=d1; %===> it's not correct because the fields have a different order
How can I add the preset to the table by correctly assign the fields?

채택된 답변

Voss
Voss 2024년 9월 8일
편집: Voss 2024년 9월 8일
Assuming the set of table variable names is the same between d1 and app.Preset_UITable.Data (but potentially in a different order):
[~,idx] = ismember(app.Preset_UITable.Data.Properties.VariableNames,d1.Properties.VariableNames);
app.Preset_UITable.Data(end+1,:) = d1(:,idx);

추가 답변 (4개)

Peter Perkins
Peter Perkins 2024년 9월 10일
Most of what's being shown in the responses is unnecessary. It's easier than that. No loops needed, not even ismember.
1) vertcat will align by variable name:
t = table("Preset_1",false,31,VariableNames=["Name" "LS" "Dwmy"])
t = 1x3 table
Name LS Dwmy __________ _____ ____ "Preset_1" false 31
d1 = table("Preset_2",31,true,VariableNames=["Name" "Dwmy" "LS"])
d1 = 1x3 table
Name Dwmy LS __________ ____ _____ "Preset_2" 31 true
[t; d1]
ans = 2x3 table
Name LS Dwmy __________ _____ ____ "Preset_1" false 31 "Preset_2" true 31
2) Assignment with indices or : on the LHS will assign positionally, which I gather is not what you want:
t(end+1,:) = d1
t = 2x3 table
Name LS Dwmy __________ _____ ____ "Preset_1" false 31 "Preset_2" true 1
In this case, it's positionally assigning 31 into a logical variable (becomes true), and true into an integer variable (becomes 1).
3) Assignment with variable names on the LHS will align:
t(end+1,d1.Properties.VariableNames) = d1
t = 3x3 table
Name LS Dwmy __________ _____ ____ "Preset_1" false 31 "Preset_2" true 1 "Preset_2" true 31

dpb
dpb 2024년 9월 8일
편집: dpb 2024년 9월 8일
Why is d1 in the reversed order? Why don't you make life simpler and reorder it to match (or vice versa with the table)?
Failing in that, at least one awkward way...
outOrder=[1:width(d1)-2 width(d1) width(d1)-1];
app.Preset_UITable.Data(end+1,outOrder)=d1;
Alternatively,
[~,ib]=ismember(app.Preset_UITable.Properties.VariableNames,d1.Properties.VariableNames);
app.Preset_UITable.Data(end+1,ib)=d1;
  댓글 수: 1
Luca Re
Luca Re 2024년 9월 8일
이동: dpb 2024년 9월 8일
"d1" is a table filled with fields that may not be sorted. The reason is that individual fields can be added or removed by changing their order Your solutions consist of recreating the correct order during assignment but I wanted an automatic way to assign each field correctly
None of the 2 proposed solutions help me
(there are more than 3 fields, I just simplified it)

댓글을 달려면 로그인하십시오.


Steven Lord
Steven Lord 2024년 9월 8일
Is d1 a struct array whose fields you need to rearrange?
d1 = dir(which('bench.m'))
d1 = struct with fields:
name: 'bench.m' folder: '/MATLAB/toolbox/matlab/general' date: '19-Jul-2023 18:24:31' bytes: 14171 isdir: 0 datenum: 7.3909e+05
If so you can use orderfields. I'm going to use fieldnames to get the list of fields in the struct and reorder them in alphabetical order, but if you have a desired order that you generated some other way you could use that order instead.
thefields = fieldnames(d1);
d2 = orderfields(d1, sort(thefields))
d2 = struct with fields:
bytes: 14171 date: '19-Jul-2023 18:24:31' datenum: 7.3909e+05 folder: '/MATLAB/toolbox/matlab/general' isdir: 0 name: 'bench.m'

Umar
Umar 2024년 9월 8일

Hi @Luca Re,

You mentioned, “"d1" is a table filled with fields that may not be sorted. The reason is that individual fields can be added or removed by changing their order Your solutions consist of recreating the correct order during assignment but I wanted an automatic way to assign each field correctly,None of the 2 proposed solutions help me, (there are more than 3 fields, I just simplified it)”

To address the issue of dynamically assigning fields from one table to another in MATLAB while ensuring that the fields are correctly matched regardless of their order, you can use the following approach. This method involves utilizing MATLAB's ability to handle tables flexibly. Here is a sample code snippet to achieve automatic field assignment:

% Create a sample UI figure and table with initial data
f = uifigure();
app.Preset_UITable = uitable(f, 'Data', table("Preset_1", false,
31, 
'VariableNames', {'Name', 'LS_', 'Dwmy'}));
% New data to be added with potentially different field order
d1 = table("Preset_2", 31, true, 'VariableNames', {'Dwmy', 
'Name', 'LS_'});
% Get the variable names from the existing table
existingVarNames = 
app.Preset_UITable.Data.Properties.VariableNames;
% Initialize an empty array for new data
newRow = cell(1, length(existingVarNames));
% Loop through the existing variable names to fill in the new row
for i = 1:length(existingVarNames)
  % Check if the current variable name exists in d1
  if ismember(existingVarNames{i}, d1.Properties.VariableNames)
      % Assign the corresponding value from d1 to newRow
      newRow{i} = d1{:, existingVarNames{i}};
  else
      % If the variable does not exist, assign a default value 
  (e.g., NaN or empty)
      newRow{i} = NaN;  % You can choose a different default 
 value as needed
  end
end
% Add the new row to the existing table data
app.Preset_UITable.Data(end+1, :) = newRow;
% Display updated table data
disp(app.Preset_UITable.Data);

I am unable to execute this code in Matlab mobile, please see attached. So, please execute this code in your MATLAB program and let me know if this helped resolve your problem.

Explanation of the Code

Table Creation: The code starts by creating a UI figure and an initial table with a specified field order.

New Data Table (d1): A new table `d1` is created with a different order of fields. The goal is to integrate this table into the existing UI table without manual reordering.

Variable Names Extraction: The existing table's variable names are extracted to ensure the new data is assigned in the correct format.

Row Initialization: An empty cell array newRow is initialized to store the values for the new row that will be added.

Field Matching Loop: A loop iterates through the existing table's variable names. For each variable name, the code checks if it exists in d1. If it does, it assigns the corresponding value from d1 to newRow. If the field is missing in d1, a default value is assigned (in this case, NaN).

Data Addition: Finally, the new row is appended to the existing table data in app.Preset_UITable.

Display Output: The updated table data is displayed to confirm the changes.

As you can glance the the code, you will find out that The use of ismember allows the code to adapt to varying field orders, making it robust against changes in the structure of the data. By following this approach, you should be able to add data to your table while making sure that the fields are assigned correctly, regardless of their order.

  댓글 수: 2
Luca Re
Luca Re 2024년 9월 8일
thank you
Umar
Umar 2024년 9월 9일
Hi @Luca Re,
You are welcome

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Characters and Strings에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by