Есть ли в Dart что-то вроде `defaultdict` в Python? - PullRequest
0 голосов
/ 14 апреля 2020

Что я хочу сделать, это ниже. Не могли бы вы научить меня, как это сделать, если это возможно?

import 'package:my_package/data_object.dart';
Map<String, List<DataObject>> m = Map<int, List<DataObject>>(); // Create an empty map.
m['001'].add(DataObject(something: something)); // Can add DataObject without checking if '001' exists.
m['002'].add(DataObject(something: something));

Ответы [ 2 ]

2 голосов
/ 14 апреля 2020

Вы можете использовать метод putIfAbsent в Map, чтобы создать и вставить, например, пустой список на карту, если он еще не существует: https://api.dart.dev/stable/2.7.2/dart-core/Map/putIfAbsent.html

void main() {
  Map<String, List<int>> m = {};

  m.putIfAbsent('001', () => []).add(1);
  m.putIfAbsent('001', () => []).add(2);
  m.putIfAbsent('002', () => []).add(3);

  print(m); // {001: [1, 2], 002: [3]}
}

Альтернативное решение

Если вы собираетесь многократно использовать этот шаблон, проще будет реализовать собственный класс Defaultdict, который не так сложен, поскольку мы просто хотим, чтобы он вел себя как карта:

import 'dart:collection';

class Defaultdict<K,V> extends MapBase<K,V> {
  final Map<K,V> _map = {};
  final V Function() _ifAbsent;

  Defaultdict(this._ifAbsent);

  @override
  V operator [](Object key) => _map.putIfAbsent(key as K, _ifAbsent);

  @override
  void operator []=(K key, V value) => _map[key] = value;

  @override
  void clear() => _map.clear();

  @override
  Iterable<K> get keys => _map.keys;

  @override
  V remove(Object key) => _map.remove(key);
}

void main() {
  // Create a Defaultdict where we return a empty new list for unknown keys
  final m = Defaultdict<String, List<int>>(() => []);

  m['001'].add(1);
  m['001'].add(2);
  m['002'].add(3);

  print(m); // {001: [1, 2], 002: [3]}
}
1 голос
/ 14 апреля 2020

Обычно я использую ??=, когда это возможно:

var m = <String, List<DataObject>>{};
(m['001'] ??= []).add(DataObject(something: something));
(m['002'] ??= []).add(DataObject(something: something));

Обратите внимание, что это не то же самое, что использование putIfAbsent, поскольку оно будет перезаписывать записи, где ключ существует, но значение равно null. Если вы никогда не сохраняете null в своем Map, используйте то, что считаете более чистым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...