# 🏅 Day 5 - 元組與聯合型別
## 元組
元組允許將不同類型的元素儲存在單一陣列內,在需要將多種數據型別組合在一起時非常有用。
### 特點
1. 元組陣列長度是固定的
2. 元素順序在宣告時就會被確定
3. 允許不同型別的資料共存
```tsc=
let userInfo: [string, number];
userInfo = ["Alice", 30]; // 正確
userInfo = [30, "Alice"]; // 錯誤:型別對不上
let profile: [string, number] = ['Mary', 18];
function getStudentDetails(studentId: number): [number, string, string] {
// 假設從資料庫獲得學生資訊
return [studentId, "John Doe", "Physics"];
}
const [id, name, course] = getStudentDetails(101);
console.log(`Student ID: ${id}, Name: ${name}, Course: ${course}`);
```
## 元組常見使用時機一:函式返回多個值
當函式需要回傳多個值時,元組是一種非常方便的方式。允許你將多個值組合成一個緊湊的資料結構,並且每個值可以有不同的型別且確保回傳的順序一致。
```typescript=
function getSize(): [number, number] {
return [width, height];
}
```
## 元組常見使用時機二:解讀 CSV 格式
在解析 csv 資料蠻派得上用場的,因為 csv 的資料通常每筆資料在取值上型別都不相同
**HTML:**
```html=
<!DOCTYPE html>
<html>
<head>
<title>CSV Parser</title>
</head>
<body>
<input type="file" id="file-input" />
<script src="parseCSV.js"></script>
</body>
</html>
```
**parseCSV.ts**
```typescript=
// 元組型別
function parseCsv(content: string): [string, number, string][] {
return content.split("\n").map(line => {
const [name, ageString, position] = line.split(",");
const age = parseInt(ageString, 10);
return [name, age, position];
});
}
function handleFileSelect(evt: any) {
const file = evt.target.files[0];
const reader = new FileReader();
reader.onload = function(event) {
const content = event.target.result as string;
const employees = parseCsv(content);
console.log(employees);
};
reader.readAsText(file);
}
document.getElementById('file-input').addEventListener('change', handleFileSelect, false);
```
**CSV 測試檔:employees.csv,請檔案儲存起來後,在 index.html 的 input file 加入後觸發 change 事件,便可看到 console 的資訊**
```csv=
John Doe,30,Developer
Jane Smith,25,Designer
Max Johnson,40,Manager
Emily Davis,35,Analyst
Alex Brown,28,Tester
```
## 聯合型別
在 TypeScript 中,聯合型別(Union Types)允許一個變數具有多個可能的型別。可增加程式碼的靈活性。
```tsx
// 範例程式碼 1
function printId(id: number | string) {
console.log(`ID: ${id}`);
}
printId(123); // 輸出: ID: 123
printId("abc"); // 輸出: ID: abc
// 範例程式碼 2
function printResult(result: string | number) {
if (typeof result === "string") {
console.log(`Result: "${result}"`);
} else {
console.log(`Result: ${result}`);
}
}
printResult("success"); // 輸出: Result: "success"
printResult(42); // 輸出: Result: 42
```
## 單選題
**1. 下列哪個選項正確描述了元組?**
- A. 元組是一種無序的資料結構
- B. 元組可以包含不同類型的值
- C. 元組的長度可以動態調整
- D. 元組的元素可以被修改
**2. 以下哪個描述最準確地表示 TypeScript 中的「聯合型別」?**
- A. 聯合型別是一種將多個不同型別組合成一個型別的方式。
- B. 聯合型別是一種用於表示陣列的型別。
- C. 聯合型別是一種用於表示物件的型別。
**3. 以下哪個 TypeScript 寫法表示一個元組(包含姓名和年齡)?**
```tsx
A. const person: [string, number] = ["John", 30];
B. const person: [string] = ["John", 30];
C. const person: { name: string; age: number } = { name: "John", age: 30 };
D. const person: (string | number)[] = ["John", 30];
```
**4. 以下哪個 TypeScript 寫法表示一個聯合型別(可以是字串或數字)?**
```tsx
A. const value: string = "Hello";
B. const value: string | number = "Hello";
C. const value: (string | number)[] = ["Hello", 42];
D. const value: { text: string } = { text: "Hello" };
```
**5. 下列哪一個元組宣告會報錯?**
```tsx
A. const a: [number, string] = [1, "a"];
B. const a: [string, number] = ["a", 1];
C. const a: [number, string] = [1, "a", 2];
D. const a: [number, string?] = [1];
```
## 實作題
**1. 設計一個函式 `calculateAvgScore`,該函式接收一個元組為參數,元組內容依序由學生姓名(字串型別)、期中考分數(型別)、期末考分數(數字型別)組成,請設計讓函式可以計算出學生的考試平均分數,最後印出 `"{學生姓名}的平均分數為:{平均分數}"`。**
**2. 設計一個函式 `operation`,該函式接收一個字串或數字型別作為參數,當接收的參數為字串時回傳該字串的長度,接收到數字時則回傳該數字平方後的結果。**
<!-- 解答:
單選題:B、A、A、B、C
實作題:
1.
function calculateAvgScore(studentScore: [string, number, number]) {
const avgScore = (studentScore[1] + studentScore[2]) / 2
console.log(`${studentScore[0]} 的平均分數為:${avgScore}`)
}
2.
function operation(value: number | string){
if (typeof value === "string"){
return value.length
} else{
return value**2
}
}
-->