🙉

【Dart】まだ暗記してるの? DartのListとMapのメソッド一覧

2022/02/26に公開
2

DartのListとMapのメソッド一覧

どうも私はコレクション操作が好きです。
一度JavaScriptに関するコレクションのメソッドについてまとめました。
https://zenn.dev/web_tips/articles/503da56f2ef8ab

本記事は上記のDart編となります。
こういうものは暗記する必要はありません。
こういう操作ができるメソッドがあったよな〜。程度で全く問題ありません。

配列(List型)

まずは配列(List型)から紹介します。

add()

  • リストの末尾に要素を追加する。
final fruits = ["orange", "banana", "melon"];
fruits.add("apple");
print(fruits);
// [orange, banana, melon, apple]

addAll()

  • リストの末尾に指定したリストを追加する。
final fruits = ["orange", "banana", "melon"];
fruits.addAll(["apple", "strawberry"]);
print(fruits);
// [orange, banana, melon, apple, strawberry]

any()

  • リストの要素が指定した条件に1つでもマッチするかどうかを判定する。
final numbers = [1, 5, 10, 100];
final result1 = numbers.any((num) => num == 5);
print(result1);
// true

final result2 = numbers.any((num) => num % 3 == 0);
print(result2);
// false

asMap()

  • リストをMap型に変換する。
    • key: インデックス(0から)
    • value: リストの要素
final fruits = ["orange", "banana", "melon"];
final map = fruits.asMap();
print(map);
// {0: orange, 1: banana, 2: melon}

clear()

  • リストの要素を全て取り除く。
final fruits = ["orange", "banana", "melon"];
fruits.clear();
print(fruits);
// []

contains()

  • リストの要素に指定した要素が含まれているかを判定する。
final fruits = ["orange", "banana", "melon"];
final result1 = fruits.contains("orange");
print(result1);
// true
  
final result2 = fruits.contains("apple");
print(result2);
// false

elementAt()

  • 指定したインデックスの要素を返却する。
  • リストの範囲外を指定した場合はRangeErrorが発生する。
final fruits = ["orange", "banana", "melon"];
final result1 = fruits.elementAt(1);
print(result1);
// banana
  
final result2 = fruits.elementAt(3);
print(result2);
// Uncaught Error: RangeError (index): Index out of range: index should be less than 3

every()

  • リストの要素が指定した条件に全てマッチするかどうかを判定する。
final numbers = [5, 10, 100];
final result1 = numbers.every((num) => num % 5 == 0);
print(result1);
// true

final result2 = numbers.every((num) => num % 10 == 0);
print(result2);
// false

expand()

  • リストの要素を0個以上の要素に展開する。
final numbers = [1, 5, 10, 100];
final result = numbers.expand((num) => [num, num * 3]).toList();
print(result);
// [1, 3, 5, 15, 10, 30, 100, 300]

fillRange()

  • リストの要素を指定した範囲で上書きする。
  • 第二引数に指定したインデックスは含まない。
final fruits = ["orange", "banana", "melon"];
fruits.fillRange(0, 2, "apple");
print(fruits); 
// [apple, apple, melon]

firstWhere()

  • リストの要素の内、指定した条件にマッチする最初の要素を返却する。
  • マッチする要素はない場合はBad stateが発生する。
final numbers = [1, 5, 10, 100];
final result1 = numbers.firstWhere((num) => num % 5 == 0);
print(result1);
// 5
  
final result2 = numbers.firstWhere((num) => num % 3 == 0);
print(result2);
// Uncaught Error: Bad state: No element

fold()

  • リストの要素を既存の要素と組み合わせて1つの要素にまとめる。
final initNumber = 0;
final numbers = [1, 5, 10, 100];
final result1 = numbers.fold<int>(
  initNumber, (previousValue, element) => previousValue + element
);
print(result1);
// 116
  
final initStr = "あ";
final strings = ["か", "さ", "た", "な"];
final result2 = strings.fold<String>(
  initStr, (previousValue, element) => previousValue + element
);
print(result2);
// あかさたな

followedBy()

  • リスト要素に指定した要素を連結したIterableを返す。
final fruits = ["orange", "banana", "melon"];
final result = fruits.followedBy(["apple", "grape"]);
print(result);
// (orange, banana, melon, apple, grape)

forEach()

  • リストの要素を順番に処理する。
final fruits = ["orange", "banana", "melon"];
fruits.forEach((fruit) => print(fruit));
// orange
// banana
// melon

// 引数の省略可能
fruits.forEach(print);
// orange
// banana
// melon

getRange()

  • リストの要素の内、指定した範囲のIterableを返す。
  • 第二引数に指定したインデックスは含まない。
final fruits = ["orange", "banana", "melon", "apple"];
final result = fruits.getRange(1, 3);
print(result);
// (banana, melon)

indexOf()

  • 指定した要素にマッチしたインデックスを返す。
  • 第二引数で探索開始位置を指定できる。
  • マッチしなければ、-1を返す。
final fruits = ["orange", "banana", "melon", "apple", "banana"];
final result1 = fruits.indexOf("banana");
print(result1);
// 1

final result2 = fruits.indexOf("banana", 1);
print(result2);
// 1
  
final result3 = fruits.indexOf("banana", 3);
print(result3);
// 4
  
final result4 = fruits.indexOf("grape");
print(result4);
// -1

indexWhere()

  • 指定した条件にマッチした最初のインデックスを返す。
  • 第二引数で探索開始位置を指定できる。
  • マッチしなければ、-1を返す。
final fruits = ["orange", "banana", "melon", "apple", "banana"];
final result1 = fruits.indexWhere((fruit) => fruit == "banana");
print(result1);
// 1

final result2 = fruits.indexWhere((fruit) => fruit == "banana", 1);
print(result2);
// 1
  
final result3 = fruits.indexWhere((fruit) => fruit == "banana", 3);
print(result3);
// 4
  
final result4 = fruits.indexWhere((fruit) => fruit == "grape");
print(result4);
// -1

insert()

  • 指定した位置に要素を追加する。
final fruits = ["orange", "banana", "melon"];
fruits.insert(1, "apple");
print(fruits);
// [orange, apple, banana, melon]

insertAll()

  • 指定した位置にリストを追加する。
final fruits = ["orange", "banana", "melon"];
fruits.insertAll(1, ["apple", "grape"]);
print(fruits);
// [orange, apple, grape, banana, melon]

join()

  • リストの要素を指定したseparatorで区切った文字列を返す。
final fruits = ["orange", "banana", "melon"];
final result1 = fruits.join("-");
print(result1);
// orange-banana-melon

final result2 = fruits.join("");
print(result2);
// orange-banana-melon
orangebananamelon

lastIndexOf()

  • 指定した要素にマッチしたインデックスを逆方向から探索して返す。
  • 第二引数で探索開始位置を指定できる。
  • マッチしなければ、-1を返す。
final fruits = ["orange", "banana", "melon", "apple", "banana"];
final result1 = fruits.lastIndexOf("banana");
print(result1);
// 4

final result2 = fruits.lastIndexOf("banana", 1);
print(result2);
// 1
  
final result3 = fruits.lastIndexOf("banana", 3);
print(result3);
// 1
  
final result4 = fruits.lastIndexOf("grape");
print(result4);
// -1

lastIndexWhere()

  • 指定した条件にマッチした最初のインデックスを逆方向から探索して返す。
  • 第二引数で探索開始位置を指定できる。
  • マッチしなければ、-1を返す。
final fruits = ["orange", "banana", "melon", "apple", "banana"];
final result1 = fruits.lastIndexWhere((fruit) => fruit == "banana");
print(result1);
// 4

final result2 = fruits.lastIndexWhere((fruit) => fruit == "banana", 1);
print(result2);
// 1
  
final result3 = fruits.lastIndexWhere((fruit) => fruit == "banana", 3);
print(result3);
// 1
  
final result4 = fruits.lastIndexWhere((fruit) => fruit == "grape");
print(result4);
// -1

lastWhere()

  • リストの要素の内、指定した条件にマッチする最後の要素を返却する。
  • マッチする要素はない場合はBad stateが発生する。
final numbers = [1, 5, 10, 100];
final result1 = numbers.lastWhere((num) => num % 5 == 0);
print(result1);
// 100
  
final result2 = numbers.lastWhere((num) => num % 3 == 0);
print(result2);
// Uncaught Error: Bad state: No element

map()

  • リストの各要素に指定した処理を実行したIterableを返す。
final numbers = [1, 5, 10, 100];
final result1 = numbers.map((num) => num * 3);
print(result1);
// (3, 15, 30, 300)
  
final result2 = numbers.map((num) => num * 10).toList();
print(result2);
// [10, 50, 100, 1000]

remove()

  • リストの要素の内、指定した最初の要素を取り除く。
  • 指定した要素は存在しない場合はエラーは起こらない。
final fruits = ["orange", "banana", "melon", "apple", "banana"];
fruits.remove("banana");
print(fruits);
// [orange, melon, apple, banana]

fruits.remove("grape");
print(fruits);
// [orange, melon, apple, banana]

removeAt()

  • リストの要素の内、指定したインデックスの要素を取り除く。
  • リストの範囲外を指定した場合はRangeErrorが発生する。
final fruits = ["orange", "banana", "melon", "apple", "banana"];
fruits.removeAt(2);
print(fruits);
// [orange, banana, apple, banana]

fruits.removeAt(5);
// Uncaught Error: RangeError: Value not in range: 5

removeLast()

  • リストの最後の要素を取り除く。
  • 空のリストにremoveLast()した場合はRangeErrorが発生する。
final fruits = ["orange", "banana", "melon", "apple", "banana"];
fruits.removeLast();
print(fruits);
// [orange, banana, melon, apple]

final emptyList = [];
emptyList.removeLast();
// Uncaught Error: RangeError (index): Index out of range: index must not be negative: -1

removeRange()

  • 指定した範囲のリストの要素を取り除く。
  • リストの範囲外を指定した場合はRangeErrorが発生する。
final fruits = ["orange", "banana", "melon", "apple", "banana"];
fruits.removeRange(1, 3);
print(fruits);
// [orange, apple, banana]

fruits.removeRange(1, 5);
// Uncaught Error: RangeError (end): Invalid value: Not in inclusive range 1..3: 

removeWhere()

  • 指定した条件にマッチする要素を取り除く。
final fruits = ["orange", "banana", "melon", "apple", "banana"];
fruits.removeWhere((fruit) => fruit.length == 5);
print(fruits);
// [orange, banana, banana]

replaceRange()

  • 指定した範囲の要素を置き換える。
final fruits = ["orange", "melon", "apple", "banana"];
fruits.replaceRange(1, 3, ["grape"]);
print(fruits);
// [orange, grape, banana]

retainWhere()

  • 指定した条件にマッチしない要素を取り除く。
final fruits = ["orange", "banana", "melon", "apple", "banana"];
fruits.retainWhere((fruit) => fruit.length == 5);
print(fruits);
// [melon, apple]

setAll()

  • 指定した開始インデックスに要素を追加する。
  • リストの範囲外のインデックスを指定すると、RangeErrorが発生する。
final fruits = ["orange", "melon", "apple", "banana"];
fruits.setAll(1, ["grape", "lemon"]);
print(fruits);
// [orange, grape, lemon, banana]
  
fruits.setAll(5, ["apple", "watermelon"]);
// Uncaught Error: RangeError (index): Invalid value: Not in inclusive range 0..4

setRange()

  • 指定した範囲の要素を、指定したスキップカウント以降のリストと置き換える。
  • 第一引数:開始インデックス
  • 第二引数:終了インデックス
  • 第三引数:置き換えるIterable
  • 第四引数:スキップカウント
final fruits = ["orange", "melon", "apple", "banana"];
fruits.setRange(1, 3, ["grape", "lemon", "watermelon"], 1);
print(fruits);
// [orange, lemon, watermelon, banana]

shuffle()

  • リストの要素をシャッフルする。
final fruits = ["orange", "melon", "apple", "banana"];
fruits.shuffle();
print(fruits);
// [apple, melon, banana, orange] (※実行によって変わる)

singleWhere()

  • 指定した条件を満たす要素が1つのみであるかを判定して、ちょうど1つの要素だった場合はその要素を返す。
  • 要素が見つからない場合は、orElseで指定した値を返すことができる。
  • 複数の要素はマッチした場合は、Bad stateが発生する。
final fruits = ["orange", "melon", "apple"];
final result1 = fruits.singleWhere((fruit) => fruit.length == 6);
print(result1);
// orange
  
final result2 = fruits.singleWhere((fruit) => fruit.length == 1, orElse: () => "not!");
print(result2);
// not!
  
final result3 = fruits.singleWhere((fruit) => fruit.length == 5);
// Uncaught Error: Bad state: Too many elements

skip()

  • 指定したインデックスより前の要素を除くIterableを返す。
  • 負の値を指定した場合は、RangeErrorが発生する。
final fruits = ["orange", "banana", "melon", "apple"];
final result1 = fruits.skip(2);
print(result1);
// (melon, apple)
  
final result2 = fruits.skip(10);
print(result2);
// ()
  
final result3 = fruits.skip(-1);
// Uncaught Error: RangeError (start): Invalid value: Not greater than or equal to 0

skipWhile()

  • 指定した条件にマッチする要素スキップした、それ以降の要素を抽出します。
final numbers = [1, 2, 3, 5, 6, 7];
final result1 = numbers.skipWhile((x) => x < 5);
print(result1);
// (5, 6, 7)

final result2 = numbers.skipWhile((x) => x != 3);
print(result2);  
// (3, 5, 6, 7)
  
final result3 = numbers.skipWhile((x) => x != 4);
print(result3);
// ()

sort()

  • リストの要素を並べ替える。
  • デフォルトの並び替えの方法はComparatorを使用している。
final numbers = [13, 2, -11, 0];
numbers.sort();
print(numbers);
// [-11, 0, 2, 13]

final ohterNumbers = ["two", "three", "four"];
ohterNumbers.sort((a, b) => a.length.compareTo(b.length));
print(ohterNumbers);
// [two, four, three]

sublist()

  • 指定した範囲の要素を返す。
  • 第二引数の終了位置を省略した場合は、終了位置としてリストのlengthを使用する。
final fruits = ["orange", "melon", "apple", "banana", "lemon"];
final result1 = fruits.sublist(1, 3);
print(result1);
// [melon, apple]

final result2 = fruits.sublist(2);
print(result2);
// [apple, banana, lemon]

take()

  • 指定した個数分の要素をIterableとして返す。
  • リストの要素数より大きい値を指定した場合は全ての要素をIterableとして返す。
final fruits = ["orange", "melon", "apple", "banana", "lemon"];
final result1 = fruits.take(3);
print(result1);
// (orange, melon, apple)

final result2 = fruits.take(100);
print(result2);
// (orange, melon, apple, banana, lemon)

takeWhile()

  • 指定した条件にマッチしなくなった要素より前の要素をIterableとして返す。
final numbers = [1, 2, 3, 5, 6, 7];
final result1 = numbers.takeWhile((num) => num < 5);
print(result1);
// (1, 2, 3)

final result2 = numbers.takeWhile((num) => num != 3);
print(result2);
// (1, 2)

toList()

  • Iterableの要素をList型として生成する。
  • 引数のデフォルトはtrueである。
  • falseを指定すると、固定長のリストとなる。
final fruits = {1: "apple", 2: "banana", 3: "lemon"};
final result1 = fruits.keys.toList();
print(result1);
// [1, 2, 3]

final result2 = fruits.values.toList(growable: false);
print(result2);
// [apple, banana, lemon]

toSet()

  • Iterableの要素をSet型として生成する。
  • 重複したものは1つになる。
final fruits = {1: "apple", 2: "banana", 3: "lemon", 4: "apple"};
final result1 = fruits.keys.toSet();
print(result1);
// {1, 2, 3, 4}

final result2 = fruits.values.toSet();
print(result2);
// {apple, banana, lemon}

where()

  • 指定した条件にマッチした要素をIterableとして返す。
final fruits = ["orange", "melon", "apple", "banana", "lemon"];
final result1 = fruits.where((fruit) => fruit.length == 6);
print(result1);
// (orange, banana)

final result2 = fruits.where((fruit) => fruit.length == 10);
print(result2);
// ()

連想配列(Map型)

次に連想配列(Map型)を紹介します。

addAll()

  • 指定した連想配列を末尾に追加する。
final fruits = {1: "apple", 2: "banana", 3: "lemon"};
fruits.addAll({4: "melon", 5: "grape"});
print(fruits);
// {1: apple, 2: banana, 3: lemon, 4: melon, 5: grape}

addEntries()

  • 指定したMapEntryを連想配列の末尾に追加する。
final fruits = {1: "apple", 2: "banana", 3: "lemon"};
fruits.addEntries({4: "grape"}.entries);
print(fruits);
// {1: apple, 2: banana, 3: lemon, 4: grape}

clear()

  • 連想配列の要素を全て取り除く。
final fruits = {1: "apple", 2: "banana", 3: "lemon"};
fruits.clear();
print(fruits);
// {}

containsKey()

  • 指定した値が連想配列のkeyにあるかどうかを判定する。
final fruits = {1: "apple", 2: "banana", 3: "lemon"};
final result1 = fruits.containsKey(1);
print(result1);
// true

final result2 = fruits.containsKey(4);
print(result2);
// false

containsValue()

  • 指定した値が連想配列のvalueにあるかどうかを判定する。
final fruits = {1: "apple", 2: "banana", 3: "lemon"};
final result1 = fruits.containsValue("banana");
print(result1);
// true

final result2 = fruits.containsValue("melon");
print(result2);
// false

forEach()

  • 連想配列のkeyとvalueを順番に処理する。
final fruits = {1: "apple", 2: "banana", 3: "lemon"};
fruits.forEach((key, value) => print("${key}: ${value}"));
// 1: apple
// 2: banana
// 3: lemon

map()

  • 連想配列のkeyとvalueに指定した処理を実行したIterableを返す。
final fruits = {1: "apple", 2: "banana", 3: "lemon"};
final result = fruits.map((key, value) => MapEntry(key * 10, "fruit-${value}"));
print(result);
// {10: fruit-apple, 20: fruit-banana, 30: fruit-lemon}

putIfAbsent()

  • 指定したkeyが連想配列に存在しない場合は値を追加する。
final fruits = {1: "apple", 2: "banana", 3: "lemon"};
fruits.putIfAbsent(4, () => "grape");
fruits.putIfAbsent(1, () => "melon");
print(fruits);
// {1: apple, 2: banana, 3: lemon, 4: grape}

remove()

  • 指定したkeyを連想配列から取り除く。
  • 指定したkeyが連想配列にない場合は何も除かない。
final fruits = {1: "apple", 2: "banana", 3: "lemon"};
fruits.remove(1);
print(fruits);
// {2: banana, 3: lemon}

fruits.remove(4);
print(fruits);
// {2: banana, 3: lemon}

removeWhere()

  • 指定した条件にマッチした要素を連想配列から取り除く。
  • 指定したkeyが連想配列にない場合は何も除かない。
final fruits = {1: "apple", 2: "lemon", 3: "banana"};
fruits.removeWhere((key, value) => key % 2 == 0);
print(fruits);
// {1: apple, 3: banana}

fruits.removeWhere((key, value) => value.length != 5);
print(fruits);
// {1: apple}

fruits.removeWhere((key, value) => value == "grape");
print(fruits);
// {1: apple}

update()

  • 指定したkeyのvalueを更新する。
  • 指定したkeyが連想配列に存在しない場合、ifAbsentを指定することで指定した値を追加できる。
  • 指定したkeyが連想配列に存在しない場合、ifAbsentを指定しないとInvalid argumentが発生する。
final fruits = {1: "apple", 2: "lemon", 3: "banana"};
fruits.update(1, (value) => "grape");
print(fruits);
// {1: grape, 2: lemon, 3: banana}

fruits.update(4, (value) => "grape", ifAbsent: () => 'grape');
print(fruits);
// {1: grape, 2: lemon, 3: banana, 4: melon}
  
fruits.update(10, (value) => "melon");
// Uncaught Error: Invalid argument (key): Key not in map.

updateAll()

  • update()を全ての要素に対して実行する。
final fruits = {1: "apple", 2: "lemon", 3: "banana"};
fruits.updateAll((key, value) => "grape");
print(fruits);
// {1: grape, 2: grape, 3: grape}

参考

https://api.dart.dev/stable/2.16.1/dart-core/List-class.html

https://api.dart.dev/stable/2.15.1/dart-core/Map-class.html

まとめ

この記事では、Dartのコレクション関数をまとめてみました。
ここで紹介した関数をうまく使って、コーディングをしてみてください。
とても便利な関数が用意されていますので!!!

Discussion

osakiosaki

こちらの記事と直接関係無くて申し訳ありませんが(Dart関連ということで...)、以下のEffective Dartに誤りがありそうと思ったのでコメントさせていただきました。good/badが逆ではないかなと思いまして。

DON’T allow an import path to reach into or out of lib.

本について連絡する機能は無いのかな?と思ったのですが、無さそうですね。
(GitHub)本の著者との連絡手段が欲しい (誤植の連絡やフィードバックなど)