Download presentation
Presentation is loading. Please wait.
1
結構陣列 (Structure Array)
方煒 台大生機系
2
傳統的資料庫 One array (database) n elements (5 in here)
n field in each element (1 in here)
3
MATLAB give you much more flexibility
5
Arrangement of data in the structure array student.
6
結構陣列的建立 每一個結構陣列(Structure Array)可以包含很多個元素 (Elements) 每個元素可以看成是一筆資料
每個元素可以包含數個欄位(Fields) 每個欄位可包含各個不同型態的資料
7
範例1: struct01.m clear student % 清除 student 變數
student.name = ‘洪鵬翔’; % 加入 name 欄位 student.id = ‘mr871912’; % 加入 id 欄位 student.scores = [58, 75, 62]; % 加入 scores 欄位 student % 秀出結果 student = name: '洪鵬翔' id: 'mr871912' scores: '[58,75,62]‘ 此時 student 即代表一個結構陣列的第一個元素,或是第一筆資料。
8
範例2: struct02.m clear student % 清除 student 變數 student.name = ‘洪鵬翔’; % 加入 name 欄位 student.id = ‘mr871912’; % 加入 id 欄位 student.scores = [58, 75, 62]; % 加入 scores 欄位 % 以下是新加入的第二筆資料 student(2).name = '邱中人'; student(2).id = 'mr872510'; student(2).scores = [25, 36, 92]; student % 秀出結果 student = 1x2 struct array with fields: Name Id scores 此時 student 即代表一個 1×2 的結構陣列。由於此結構陣列已漸趨複雜,MATLAB 並不將所有欄位值印出。 欲顯示某元素的特定欄位值,可輸入明確的敘述,例如 student(2).scores 等。
9
範例3: 另一個建立結構陣列的方法 使用 struct 指令,其格式如下:
structureArray = struct(field1, value1, field2, value2,….) 其中 field1、field2、…是欄位名稱,value1、value2、…則是欄位所包含的資料。 如果 value1、value2、…為異質陣列,則 MATLAB 為依序將異質陣列的每個元素設定為每一個結構中相對應的欄位值。
10
範例3: struct03.m student = struct('name', {'張庭碩', '張庭安'}, 'scores', {[50 60], [60 70]}); student(1) % 顯示 student(1) student(2) % 顯示 student(2) ans = name: '張庭碩‘ scores: [50 60] name: '張庭安' scores: [60 70] 在上述使用法中,{‘張庭碩’, ‘張庭安’} 和 {[50 60], [60 70]} 都是異質陣列,因此他們的每個元素會被依次設定到每個結構之中。但是如果其中有一個異值陣列的長度是1,那麼 MATLAB 會進行「純量展開」(Scalar Expansion)來自動補足,如範例四。
11
範例4: struct04.m student = struct('name', '張庭安‘,'scores', {[50 60], [90 100]}); student(1) % 顯示 student(1) student(2) % 顯示 student(2) ans = name: '張庭安' scores: [50 60] scores: [90 100] 在上述範例中,「張庭安」可視為異質陣列的一個元素,因此在設定至 student 結構陣列時,MATLAB 會進行純量展開,將「張庭安」分別設定到 student 的兩個元素的 name 欄位值。
12
範例5: struct05.m 結構陣列可以是巢狀(Nested)的,也就是說,結構陣列的欄位可是另一個結構陣列,我們可以藉此產生複雜的資料結構 student = struct('name', {'張庭碩', '張庭安'}, 'scores', {[50 60], [60 70]}); student(2).course(1).title = 'Web Programming'; student(2).course(1).credits = 2; student(2).course(2).title = 'Numerical Method'; student(2).course(2).credits = 3; student(2).course ans = 1x2 struct array with fields: title credits
13
範例6:buildStruct01.m 1 x 3 1 x 4 取用及改變結構陣列的資料:
clear student % 清除 student 變數 student(1) = struct('name', 'Banny', 'scores', [85,80,92,78]); student(2) = struct('name', 'Joey', 'scores', [80,85,90,88]); student(3) = struct('name', 'Betty', 'scores', [88,82,90,80]); 上述的 student 結構陣列,可圖示如下: Student結構陣列 1 x 3 Student(1) Student(2) Student(3) .name=‘banny’ .scores=[85,80,92,78] .name=‘joey’ .scores=[80,85,90,88] .name=‘batty’ .scores=[88,82,90,80] 1 x 4
14
叫出結構陣列內容 使用「句點」(”.”)來找出某一筆資料內的某一個特定欄位值 例如:想看看第二個學生是誰:
>> studentName = student(2).name studentName = Joey
15
改變結構陣列內容 用assign ”=”可以改變結構陣列中個別欄位的資料內容 例如:
>> student(2).name = 'Alex'; student(2) 的姓名已由原先的 Joey 改變為 Alex。
16
Struct2cell指令 欲取用結構陣列中所有元素內所有欄位的資料,可用 struct2cell 指令,例如:
>> values = struct2cell(student) values(:,:,1) = 'Banny' [1x4 double] values(:,:,2) = 'Joey' values(:,:,3) = 'Betty' 傳回的 values 是一個異質陣列 若輸入 struct2cell 指令的結構變數維度為 m×n,且包含 p 個欄位,則傳回異質陣列的維度為 p×m×n。(在上例中,p = 2,m = 1, n = 3。)
17
Multidimensional Arrays
Consist of two-dimensional matrices “layered” to produce a third dimension. Each “layer” is called a page. Creates a new array by concatenating the arrays A,B,C, and so on along the dimension n. cat(n,A,B,C, ...)
18
CAT指令 MATLAB 提供了 cat 指令,以達到「並排欄位值」的目的,其語法為:
A = cat(dim, structureField) 其中,dim 代表並排後所改變的維度。例如,欲將小考成績左右(水平)並排,可輸入: >> cat(2, student.scores) % 2 代表左右並排以改變直行的維度 ans = 欲將小考成績上下(垂直)並排,可輸入: >> cat(1, student.scores) % 1 代表上下並排以改變橫列的維度
19
計算平均: mean 指令 mean 指令是對矩陣的每一直行進行平均值運算 計算每次考試(共四次)的平均分數,可輸入:
>> cat(1, student.scores) ans = 計算每次考試(共四次)的平均分數,可輸入: >> mean(cat(1, student.scores))
20
計算平均: mean 指令 計算每位學生(共三位)的平均分數:
>> average2 = mean(cat(1,student.scores)') average2 =
21
並排運算的兩種方式 方括弧運算:可以左右合併結構陣列中相同欄位的數值矩陣,產生一個新的數值矩陣。
把 scores 欄位值進行左右合併: >> allScores = [student.scores] allScores = 大括弧運算:可以左右合併結構陣列中相同欄位的資料,產生一個異質矩陣。 把 name 欄位值抽取出來,形成由字串組成的異質陣列: >> allNames = {student.name} allNames = 'Banny' 'Alex' 'Betty'
22
範例7: printStruct01.m clear student % 清除 student 變數
student(1) = struct('name', '張庭碩', 'scores', [85, 80]); student(2) = struct('name', '鍾書蓉', 'scores', [80, 85]); student(3) = struct('name', '黃念中', 'scores', [88, 82]); for i = 1:length(student) % 顯示出每個學生的名字 fprintf ('student %g: %s\n', i, student(i).name); end student 1: 張庭碩 student 2: 鍾書蓉 student 3: 黃念中
23
Common Structure functions
24
Structure functions Function Description
names = fieldnames(S) F = getfield(S,’field’) isfield(S,’field’) Description Returns the field names associated with the structure array S as names, a cell array of strings. Returns the contents of the field ’field’ in the structure array S. Equivalent to F = S.field. Returns 1 if ’field’ is the name of a field in the structure array S, and 0 otherwise.
25
Structure functions S = rmfield(S,’field’) S = setfield(S,’field’,V)
S = struct(’f1’,’v1’,’f2’,’v2’,...) Removes the field ’field’ from the structure array S. Sets the contents of the field ’field’ to the value V in the structure array S. Creates a structure array with the fields ’f1’, ’f2’, having the values ’v1’, ’v2’,
26
取得及改變欄位資料 亦可用 getfield及setfield來取得及改變一個欄位的資料 其指令使用格式如下:
fieldValues = getfield (structureArray, {arrayIndex}, field, {fieldIndex}) newStructure = setfield (structureArray, {arrayIndex}, field,{fieldIndex}) 輸入下列運算式即可取得第二位學生的第一次小考成績: >> score3 = getfield(student, {2}, 'scores', {1}) 可簡化為 >> score3 = student(2).scores(1); 若欲改變第二位學生的第三次小考成績,可輸入如下: >> student = setfield(student, {2}, 'scores', {1}, 75); >> student(2).scores(1)=75;
27
範例8:deal01.m myStruct = struct('name', {'Tim', 'Annie'}, 'age', {10, 13}); [myStruct.name] = deal('Roger', 'Sue'); fprintf('myStruct(1).name = %s\n', myStruct(1).name); fprintf('myStruct(2).name = %s\n', myStruct(2).name); myStruct(1).name = Roger myStruct(2).name = Sue
28
範例9: fieldNames01.m 取用及改變結構陣列的欄位 (fieldnames 指令)
student = struct('name', 'Roland', 'scores', [80, 90]); allFields = fieldnames(student) allFields = 'name' 'scores' 傳回的結果是一個字串異質陣列(Cell Array of Strings),包含了 student 的所有欄位。 欲增加一個新的欄位,直接將此欄加入於任一陣列元素即可
29
範例10: addField01.m MATLAB 會將新欄位加入其他元素,並設定其預設值為 [](空矩陣)。 ans =
clear student % 清除 student 變數 student = struct('name', 'Roland', 'scores', [80, 90]); student(2).age = 20; % 加入新欄位 student(1) % 顯示 student(1) student(2) % 顯示 student(2) ans = name: 'Roland' scores: [80 90] age: [] name: [] scores: [] age: 20 MATLAB 會將新欄位加入其他元素,並設定其預設值為 [](空矩陣)。
30
範例11:rmField01.m rm: remove
student = struct('name', 'Roland', 'scores', [80, 90]) student2 = rmfield(student, 'scores') % 刪除 scores 欄位 student = name: 'Roland' scores: [80 90] student2 = rm: remove
31
範例12: isstruct01.m 可用 isstruct 指令來測試某個變數是否為結構陣列:
s = struct('name', {'Tim', 'Ann'}, 'scores', {[1 3 5 ],[2 4 6]}); isstruct(s) ans = 1
32
範例13: isstruct02.m 因 s 並不包含“height”的欄位,故回傳數值 0。
可用 isfield 指令測試某結構陣列是否含一特定欄位: s = struct('name', {'Tim', 'Ann'}, 'scores', {[1 3 5 ],[2 4 6]}); fprintf('isfield(s, ''name'') = %d\n', isfield(s, 'name')); fprintf('isfield(s, ''height'') = %d\n', isfield(s, 'height')); isfield(s, 'name') = 1 isfield(s, 'height') = 0 因 s 並不包含“height”的欄位,故回傳數值 0。
33
範例14: cell2struct01.m 可用 cell2struct 指令來將異質陣列轉換成結構陣列: fields = {'name', 'age'}; values = {'Tim', 9; 'Annie', 6}; s = cell2struct(values, fields, 2); s(1) %顯示第一筆資料 s(2) %顯示第二筆資料 ans = name: 'Tim' age: 9 name: 'Annie' age: 6 根據陣列變數 fields 的資料為欄位名稱,並以 values 的第二個維度來對應欄位名稱 fields,來產生一個結構陣列 s。
34
範例15:cell2struct02.m 如果以 values 的第一個維度來對應欄位名稱 fields,結果如下:
fields = {'name', 'age'}; values = {'Tim', 9; 'Annie', 6}; s = cell2struct(values, fields, 1); s(1) % 顯示第一筆資料 s(2) % 顯示第二筆資料 ans = name: 'Tim' age: 'Annie' name: 9 age: 6
35
範例16: dir01.m dir 指令傳回一結構陣列,包含現在目錄(或資料夾)下各種資訊
dirinfo = dir(matlabroot) % 字串變數 matlabroot 代表 MATLAB 根目錄 dirinfo = 19x1 struct array with fields: name date bytes isdir dirinfo 為一結構陣列,內含在 MATLAB 根目錄下所含檔案或其他目錄的資訊,即其名稱(name),產生日期(date),大小(bytes),及是否為目錄(isdir)等。
36
One array With 3 elements containing 6 fields
練習:建立以下結構陣列 One array With 3 elements containing 6 fields
Similar presentations