【Flutter】扩展 Map 对象功能

Dart 的 Map 对象虽然已经比较好用,但总有不满足的地方。
比如说,我想在 map 中取 key 为 'a' 的 int 类型数据,成功取到就用取到的值,取失败就用默认值,甚至如果是一个字符串类型的数值,我也希望能转成 int 给我。
要实现这些操作,如果不做点什么,就要写不少的判断什么的代码。如果一两个地方需要也就罢了,要是很多地方需要,那就有很多重复的代码了。

好在 dart 为我们提供了 extension 关键字,可以很方便的对现有类型进行功能扩展。废话不多说了,直接上代码,抛砖引玉,不喜勿喷!


import 'dart:convert';
import 'utils.dart';

/// Map 扩展
extension MapExtension on Map {
  /// 取对象
  _Set<Object?> get o => _Set((key) => key == null ? null : this[key]);
  /// 取字符串
  _Set<String> get s => _Set((key) => getString(key));
  /// 取整数
  _Set<int> get i => _Set<int>((key) => getInt(key));
  /// 取浮点数
  _Set<double> get f => _Set<double>((key) => getFloat(key));
  /// 取日期时间
  _Set<DateTime?> get d => _Set<DateTime?>((key) => getDateTime(key));
  /// 取列表
  _Set<List<dynamic>> get list => _Set<List<dynamic>>((key) => getList(key, (item) => item));

  /// 获取字符串
  String getString(final String? key, [final String defaultValue = '']) {
    if (key == null) return defaultValue;
    var _v = this[key];
    if (_v == null) return defaultValue;
    if (_v is String) return _v;
    return "$_v";
  }

  /// 获取整数
  int getInt(final String? key, [final int defaultValue = 0]) {
    if (key == null) return defaultValue;
    var _v = this[key];
    if (_v == null) return defaultValue;
    if (_v is int) return _v;
    return Utils.toInt("$_v", 0);
  }

  /// 获取浮点数
  double getFloat(final String? key, [final double defaultValue = 0.0]) {
    if (key == null) return defaultValue;
    return Utils.toFloat(this[key], defaultValue);
  }

  /// 获取时间
  DateTime? getDateTime(final String? key, [final DateTime? defaultValue]) {
    if (key == null) return defaultValue;
    Object? v = this[key];
    if (v == null) return defaultValue;
    if (v is DateTime) return v;
    if (v is int) return DateTime.fromMillisecondsSinceEpoch(v);
    return DateUtil.toDateTime("$v", defaultValue);
  }

  /// 获取列表
  /// [initClassCallback] - 根据item生成[T]类实例
  List<T> getList<T>(final String? key, T Function(dynamic item)? initClassCallback) {
    List<T> items = [];
    if (key == null) return items;
    Object? _items = this[key];
    if (_items != null && (_items is List) && initClassCallback != null) {
      for (var item in _items) {
        items.add(initClassCallback(item));
      }
    }
    return items;
  }

  /// 转为 JSON 字符串
  String toJson() {
    return const JsonEncoder().convert(this);
  }

  /// Json 对象转为 Map
  static Map fromJson(final String data) {
    return const JsonDecoder().convert(data);
  }
}

class _Set<T> {
  final T Function(String? key) onGetData;
  _Set(this.onGetData);

  T operator [](final String? key) {
    return onGetData(key);
  }
}


在将上面的代码保存后在任意文件中引入后,就可以这样使用了:


Map v = {'a': '123', 'b': '456', 'c': 666, 'items': ['a', 'b', 'c', 1, 2, 3] };
print(v.s['a']);
print(v.i['b']);
print(v.s['c']);
print(v.getList<Stirng>('items', (e) => e.toString()));

posted @ 2022-04-21 17:01  我爱我家喵喵  阅读(228)  评论(0编辑  收藏  举报