Dart 的集合(Set)是一種無序且不重複的資料結構,適用於需要確保元素唯一性的場景。其內建方法如 addremoveaddAll 可便捷地操作元素。for-in 迴圈則提供了迭代 Set 元素的有效方式。需要注意的是,直接複製 Set 變數只會建立參照,修改複製後的集合會影響原始集合。利用 toSet() 方法可以建立 Set 的副本,避免此問題。 Dart 也提供 unionintersectiondifference 等方法進行集合運算,方便處理多個 Set 之間的關係。結合 List 和 Set 可以高效地找出列表中的重複元素或唯一元素。理解 Set 的特性和操作方法,能有效提升 Dart 程式碼的效率和簡潔性,特別是在需要處理大量資料並確保資料唯一性的情況下。

新增元素

你可以使用 add 方法將元素新增到集合中。例如:

var drinks = {'water'};
drinks.add('cola');
print(drinks); // {water, cola}

如果你嘗試新增相同的元素多次,集合只會保留一個副本。

移除元素

你可以使用 remove 方法從集合中移除元素。例如:

drinks.remove('water');
print(drinks); // {cola}

新增多個元素

你可以使用 addAll 方法將多個元素新增到集合中。例如:

drinks.addAll(['juice', 'coffee', 'milk']);
print(drinks); // {cola, juice, coffee, milk}

迭代集合

你可以使用 for-in 迴圈迭代集合的元素。例如:

for (final drink in drinks) {
  print("I'm drinking $drink.");
}

這會輸出:

I'm drinking cola.
I'm drinking juice.
I'm drinking coffee.
I'm drinking milk.

注意,雖然集合不保證元素的順序,但 Dart 的預設集合實作 LinkedHashSet 會維護新增元素的順序。

複製集合

集合的元素是可變的,就像列表的元素一樣。如果你忘記了這一點,你可能會對集合的複製行為感到驚訝。例如:

var originalSet = {'a', 'b', 'c'};
var copiedSet = originalSet;
copiedSet.add('d');
print(originalSet); // {a, b, c, d}

這是因為 copiedSet 只是對 originalSet 的參照,而不是一個新的集合副本。

在上面的程式碼中,我們使用 add 方法將元素新增到集合中,使用 remove 方法從集合中移除元素,使用 addAll 方法將多個元素新增到集合中,使用 for-in 迴圈迭代集合的元素。注意,集合的元素是可變的,就像列表的元素一樣。

  graph LR
    A[集合] --> B[新增元素]
    B --> C[移除元素]
    C --> D[新增多個元素]
    D --> E[迭代集合]
    E --> F[複製集合]

這個圖表展示了集合的基本操作,包括新增元素、移除元素、新增多個元素、迭代集合和複製集合。

瞭解集合(Sets)在Dart中的運用

在Dart中,集合(Sets)是一種用於儲存唯一元素的資料結構。與列表(Lists)不同,集合不允許重複的元素。這使得集合非常適合於儲存一組唯一的物件。

集合的基本操作

以下是集合的一些基本操作:

void main() {
  // 建立一個集合
  Set<String> drinks = {'cola', 'juice', 'coffee', 'milk'};
  
  // 列印集合
  print(drinks);
  
  // 從集合中移除一個元素
  drinks.remove('milk');
  
  // 列印更新後的集合
  print(drinks);
}

這段程式碼建立了一個名為drinks的集合,包含四種飲料。接著,它移除milk從集合中,並列印更新後的集合。

集合的複製

如果你需要複製一個集合,可以使用toSet()方法:

void main() {
  // 建立一個集合
  Set<String> drinks = {'cola', 'juice', 'coffee', 'milk'};
  
  // 複製集合
  Set<String> liquids = drinks.toSet();
  
  // 列印原始集合
  print(drinks);
  
  // 從複製的集合中移除一個元素
  liquids.remove('coffee');
  
  // 列印更新後的原始集合和複製的集合
  print(drinks);
  print(liquids);
}

這段程式碼建立了一個名為drinks的集合,然後複製它到一個名為liquids的新集合中。接著,它移除coffeeliquids集合中,並列印更新後的原始集合和複製的集合。

集合的其他操作

集合支援許多其他操作,包括:

  • add(): 向集合中新增一個元素。
  • remove(): 從集合中移除一個元素。
  • contains(): 檢查集合中是否包含一個元素。
  • union(): 傳回兩個集合的聯合。
  • intersection(): 傳回兩個集合的交集。
  • difference(): 傳回兩個集合的差集。

以下是這些操作的示例:

void main() {
  // 建立兩個集合
  Set<String> setA = {'1', '2', '3', '4'};
  Set<String> setB = {'3', '4', '5', '6'};
  
  // 聯合
  Set<String> union = setA.union(setB);
  print(union);
  
  // 交集
  Set<String> intersection = setA.intersection(setB);
  print(intersection);
  
  // 差集
  Set<String> difference = setA.difference(setB);
  print(difference);
}

這段程式碼建立兩個集合setAsetB,然後計算它們的聯合、交集和差集。

集合與列表的運用

在 Dart 中,集合(Set)和列表(List)是兩種不同的資料結構。集合是一種無序的資料結構,裡面的元素不允許重複,而列表是一種有序的資料結構,裡面的元素可以重複。

集合的基本操作

集合提供了多種基本操作,例如新增元素、檢查元素是否存在、移除元素等。以下是幾個例子:

  • 新增元素:animals.add('sheep')
  • 檢查元素是否存在:animals.contains('sheep')
  • 移除元素:animals.remove('sheep')

集合之間的關係

當我們有多個集合時,可能需要知道它們之間的關係。例如,兩個集合之間的交集、聯集、差集等。

交集

交集是兩個集合之間的共同元素。例如,集合 A 和集合 B 的交集是 {1, 4}

final setA = {8, 2, 3, 1, 4};
final setB = {1, 6, 5, 4};
final intersection = setA.intersection(setB);
print(intersection); // {1, 4}

聯集

聯集是兩個集合之間的所有元素。例如,集合 A 和集合 B 的聯集是 {8, 2, 3, 1, 4, 6, 5}

final setA = {8, 2, 3, 1, 4};
final setB = {1, 6, 5, 4};
final union = setA.union(setB);
print(union); // {8, 2, 3, 1, 4, 6, 5}

差集

差集是集合 A 中的元素,集合 B 中沒有的元素。例如,集合 A 和集合 B 的差集是 {8, 2, 3}

final setA = {8, 2, 3, 1, 4};
final setB = {1, 6, 5, 4};
final difference = setA.difference(setB);
print(difference); // {8, 2, 3}

列表的基本操作

列表提供了多種基本操作,例如新增元素、檢查元素是否存在、移除元素等。以下是幾個例子:

  • 新增元素:list.add('sheep')
  • 檢查元素是否存在:list.contains('sheep')
  • 移除元素:list.remove('sheep')

Spread Operator

Spread operator 是一個用於將集合或列表中的元素新增到另一個集合或列表中的運算子。例如:

final listA = [1, 2, 3];
final listB = [4, 5, 6];
final listC = [...listA, ...listB];
print(listC); // [1, 2, 3, 4, 5, 6]

Dart 中的集合運算

在 Dart 中,集合(Set)是一種用於儲存唯一元素的資料結構。集合運算是指對兩個或多個集合進行的運算,例如聯集、交集、差集等。

聯集(Union)

聯集是指兩個集合的所有元素的集合。例如,集合 A = {1, 2, 4} 和集合 B = {1, 3, 4, 5, 6},則聯集為 {1, 2, 3, 4, 5, 6}。

在 Dart 中,可以使用 union() 方法來計算聯集:

final setA = {1, 2, 4};
final setB = {1, 3, 4, 5, 6};
final union = setA.union(setB);
print(union); // {1, 2, 3, 4, 5, 6}

交集(Intersection)

交集是指兩個集合的共同元素的集合。例如,集合 A = {1, 2, 4} 和集合 B = {1, 3, 4, 5, 6},則交集為 {1, 4}。

在 Dart 中,可以使用 intersection() 方法來計算交集:

final setA = {1, 2, 4};
final setB = {1, 3, 4, 5, 6};
final intersection = setA.intersection(setB);
print(intersection); // {1, 4}

差集(Difference)

差集是指一個集合中包含的元素,但另一個集合中不包含的元素。例如,集合 A = {1, 2, 4} 和集合 B = {1, 3, 4, 5, 6},則 A - B = {2},B - A = {3, 5, 6}。

在 Dart 中,可以使用 difference() 方法來計算差集:

final setA = {1, 2, 4};
final setB = {1, 3, 4, 5, 6};
final differenceA = setA.difference(setB);
print(differenceA); // {2}
final differenceB = setB.difference(setA);
print(differenceB); // {3, 5, 6}
  graph LR
    A[集合 A] -->|聯集| C[聯集]
    B[集合 B] -->|聯集| C
    A -->|交集| D[交集]
    B -->|交集| D
    A -->|差集| E[差集 A - B]
    B -->|差集| F[差集 B - A]

在這個圖表中,集合 A 和集合 B 進行聯集、交集和差集運算,得到不同的結果。

集合運算與隨機數生成

集合運算

集合(Set)是一種資料結構,用於儲存唯一的元素。下面,我們將實作集合的交集和聯集運算。

void main() {
  // 定義三個集合
  final nullSafe = {'Swift', 'Dart', 'Kotlin'};
  final pointy = {'Sword', 'Pencil', 'Dart'};
  final dWords = {'Dart', 'Dragon', 'Double'};

  // 集合交集
  final intersection = nullSafe.intersection(pointy);
  print('交集:$intersection');

  // 集合聯集
  final union = nullSafe.union(pointy);
  print('聯集:$union');
}

隨機數生成

隨機數生成是許多應用程式中的一個重要功能,尤其是在遊戲中。下面,我們將使用Dart的Random類別生成隨機數。

import 'dart:math';

void main() {
  // 建立一個隨機數生成器
  final randomGenerator = Random();

  // 生成10個1-10之間的隨機整數
  final randomIntList = <int>[];
  for (int i = 0; i < 10; i++) {
    final randomInt = randomGenerator.nextInt(10) + 1;
    randomIntList.add(randomInt);
  }

  print('隨機整數列表:$randomIntList');
}

檢查列表中是否有重複元素

使用集合可以快速地檢查列表中是否有重複元素。

void main() {
  // 定義一個列表
  final list = [1, 2, 3, 4, 5, 2, 3];

  // 將列表轉換為集合
  final set = Set.from(list);

  // 檢查集合的大小是否小於列表的大小
  if (set.length < list.length) {
    print('列表中有重複元素');
  } else {
    print('列表中沒有重複元素');
  }
}
  flowchart TD
    A[開始] --> B[生成隨機數]
    B --> C[檢查列表中是否有重複元素]
    C --> D[輸出結果]

此圖表展示了程式的流程,從開始到生成隨機數,然後檢查列表中是否有重複元素,最後輸出結果。

Dart 中的集合:Sets 和 Lists

在 Dart 中,Set 是一個不允許重複元素的集合。這意味著,如果你嘗試新增一個已經存在於集合中的元素,集合不會發生任何改變。這個特性使得 Set 非常適合於找出列表中唯一的元素或是從列表中移除重複的元素。

找出列表中的重複元素

假設我們有一個整數列表 randomIntList,我們可以使用 Set 來找出列表中的重複元素。以下是實作的步驟:

  1. 建立兩個空的 Set:一個用於儲存列表中的唯一元素,另一個用於儲存重複的元素。
  2. 遍歷列表中的每個元素。如果元素已經存在於唯一元素的集合中,則將其新增到重複元素的集合中。否則,將其新增到唯一元素的集合中。
  3. 打印出重複元素的集合。

以下是實作的程式碼:

void main() {
  List<int> randomIntList = [8, 3, 2, 3, 7, 7, 4, 5, 6, 2];

  Set<int> uniqueValues = {};
  Set<int> duplicates = {};

  for (int number in randomIntList) {
    if (uniqueValues.contains(number)) {
      duplicates.add(number);
    } else {
      uniqueValues.add(number);
    }
  }

  print(duplicates);
}

這段程式碼會輸出重複的元素,例如:{2, 3, 7}

尋找唯一元素

如果你只想找出列表中的唯一元素,可以直接使用 toSet() 方法將列表轉換為集合。這會自動移除重複的元素。

Set<int> uniqueValues = randomIntList.toSet();
print(uniqueValues);

這會輸出唯一的元素,例如:{8, 3, 2, 7, 4, 5, 6}

對稱差

對稱差(Symmetric Difference)是兩個集合中不相交的元素的集合。可以使用 Set 來計算兩個集合的對稱差。

Set<int> setA = {2, 1, 4, 8, 3, 5, 6};
Set<int> setB = {4, 5, 6, 7, 8, 9};

Set<int> symmetricDifference = setA.union(setB).difference(setA.intersection(setB));
print(symmetricDifference);

這會輸出兩個集合中不相交的元素,例如:{1, 2, 3, 7, 9}

Maps 在 Dart 中的應用

Maps 在 Dart 中是一種用於儲存鍵值對的資料結構,類似於其他語言中的雜湊表和字典。如果你不熟悉 Maps,可以把它們想象成一組變數的集合,每個變數都包含了某些資料。鍵就像變數名稱,而值就是變數所持有的資料。要找到某個特定的值,只需要給 Maps 提供鍵的名稱就可以了。

建立一個 Map

與 List 和 Set 一樣,Map 也是一種泛型型別,但它需要兩個型別引數:一個是鍵的型別,另一個是值的型別。你可以使用 Map 並指定鍵和值的型別來建立一個空的 Map 變數:

final Map<String, int> emptyMap = {};

在這個例子中,String 是鍵的型別,而 int 是值的型別。也可以使用更簡短的方式來建立 Map:

final emptyMap = <String, int>{};

注意,Maps 也使用大括號,就像 Sets 一樣。如果你寫了以下程式碼:

final emptySomething = {};

你會得到什麼?是 Set 還是 Map?

事實上,Dart 的歷史上,Map 文字先於 Set 文字,所以 Dart 會將空的大括號推斷為 <dynamic, dynamic> 型別的 Map,也就是說鍵和值的型別都是 dynamic。如果你想要建立一個 Set 而不是 Map,就需要明確指出:

final mySet = <String>{};

單個 String 型別在角括號內可以明確指出這是一個 Set 而不是 Map。

初始化 Map 的值

你可以使用 Map 文字來初始化 Map 的值,這被稱為 Map 文字。例如:

final inventory = {
  'cakes': 20,
  'pies': 14,
  'donuts': 37,
  'cookies': 141,
};

這種方式可以方便地建立一個 Map 並初始化其值。

Maps 的應用

Maps 的應用非常廣泛,例如可以用來儲存資料、查詢特定的值等。在 Dart 中,Maps 是一種非常重要的資料結構,需要熟練掌握其使用方法。

上述程式碼建立了一個 Map 並初始化其值,使用 Map 文字可以方便地建立 Map 並初始化其值。Maps 的應用非常廣泛,需要熟練掌握其使用方法。

  graph LR
    A[建立 Map] --> B[初始化 Map 的值]
    B --> C[使用 Map]
    C --> D[查詢特定的值]
    D --> E[儲存資料]

上述圖表展示了建立 Map、初始化 Map 的值、使用 Map、查詢特定的值和儲存資料的過程。Maps 的應用非常廣泛,需要熟練掌握其使用方法。

Dart 中的 Map

Dart 的 Map是一種鍵值對(key-value pair)的集合,使用型別推斷來識別鍵和值的型別。在以下的例子中,inventory是一個 Map,鍵是字串,值是整數。

final inventory = {
  'cakes': 20,
  'pies': 14,
  'donuts': 37,
  'cookies': 141,
};

在這個例子中,Dart 使用型別推斷來識別 inventory 是一個 Map,鍵是字串,值是整數。鍵和值之間用冒號(:)分隔,多個鍵值對之間用逗號(,)分隔。

鍵的型別

鍵不一定要是字串,也可以是其他型別。例如,以下是一個 Map,鍵是整數,值是字串。

final digitToWord = {
  1: 'one',
  2: 'two',
  3: 'three',
  4: 'four',
};

獨特的鍵

Map 的鍵必須是獨特的,不能有重複的鍵。例如,以下的 Map 是無效的,因為有兩個鍵名為 gold

final treasureMap = {
  'garbage': 'in the dumpster',
  'glasses': 'on your head',
  'gold': 'in the cave',
  'gold': 'under your mattress',
};

如果需要有多個值與同一個鍵相關聯,可以使用 List 作為值的型別。

final treasureMap = {
  'garbage': ['in the dumpster'],
  'glasses': ['on your head'],
  'gold': ['in the cave', 'under your mattress'],
};

值的型別

值不需要是獨特的,可以有多個鍵對應到相同的值。

final myHouse = {
  'bedroom': 'messy',
  'kitchen': 'messy',
  'living room': 'messy',
  'code': 'clean',
};

在這個例子中,我們建立了四個 Map,分別是 inventorydigitToWordtreasureMapmyHouse。每個 Map 都有不同的鍵和值的型別,展示了 Map 的多樣性和靈活性。透過這些例子,我們可以看到 Map 是如何用來儲存和管理資料的。

Dart 中的 Map 操作

Dart 提供了方便的方式來存取、新增、刪除、更新和遍歷 Map 中的鍵值對。

存取鍵值對

您可以使用類似於列表的下標語法來存取 Map 中的鍵值對。以下範例使用先前建立的 inventory Map:

final inventory = {
  'cakes': 20,
  'pies': 14,
  'donuts': 37,
  'cookies': 141,
};

新增元素到 Map

您可以簡單地使用鍵值對的語法來新增新元素到 Map 中:

inventory['brownies'] = 3;
print(inventory);
// {cakes: 20, pies: 14, donuts: 37, cookies: 141, brownies: 3}

更新元素

請記住,Map 中的鍵是唯一的,所以如果您為已經存在的鍵指定,您將覆蓋現有的值:

inventory['cakes'] = 1;
print(inventory);
// {cakes: 1, pies: 14, donuts: 37, cookies: 141, brownies: 3}

刪除元素從 Map

您可以使用 remove 方法來刪除元素從 Map 中:

inventory.remove('cookies');
print(inventory);
// {cakes: 1, pies: 14, donuts: 37, brownies: 3}

存取屬性

Map 有屬性,就像列表一樣。例如,以下屬性指示 Map 是否為空:

print(inventory.isEmpty); // false
print(inventory.isNotEmpty); // true
print(inventory.length); // 4

您也可以使用 keysvalues 屬性來存取鍵和值:

print(inventory.keys);
print(inventory.values);

上述範例展示瞭如何使用 Dart 中的 Map 類別來存取、新增、刪除和更新鍵值對。Map 是一個強大的資料結構,可以用來儲存和操作鍵值對。透過使用 Map,您可以輕鬆地實作資料的儲存和查詢。

  graph LR
    A[Map] --> B[鍵值對]
    B --> C[存取]
    C --> D[新增]
    D --> E[刪除]
    E --> F[更新]
    F --> G[屬性]
    G --> H[鍵]
    H --> I[值]

上述圖表展示了 Map 的基本結構和操作。Map 中的鍵值對可以被存取、新增、刪除和更新。Map 也有屬性,可以用來存取鍵和值。

使用 Dart 進行 Map 運算

在 Dart 中,Map 是一個重要的資料結構,允許您儲存鍵值對(key-value pairs)。以下是如何使用 Map 來儲存和操作資料。

從技術架構視角來看,Dart 的 Set 和 Map 提供了高效且簡潔的資料結構操作方式。Set 的不重複特性使其在需要唯一性資料的場景中表現出色,例如去除重複元素、集合運算等。Map 的鍵值對結構則提供了更靈活的資料組織方式,方便資料的儲存和檢索。然而,需要注意的是,Dart 的 Set 預設實作為 LinkedHashSet,保留了元素插入順序,但這並非所有 Set 實作的通用特性。同時,Map 的鍵的唯一性限制需要開發者妥善處理潛在的鍵衝突問題。對於追求極致效能的應用,需要根據實際情況選擇合適的 Set 和 Map 實作,並考量其效能特性。展望未來,隨著 Dart 語言的持續發展,預計 Set 和 Map 的 API 和效能將得到進一步最佳化,並可能引入新的特性以滿足更多應用場景的需求。對於開發者而言,深入理解 Set 和 Map 的底層實作原理,並根據實際需求選擇合適的資料結構和操作方法,將有助於提升應用程式的效能和可維護性。玄貓認為,熟練掌握 Dart 的集合操作,對於構建高效且穩定的應用程式至關重要。