【问题标题】:Conditional member access for map children?地图子项的条件成员访问?
【发布时间】:2018-07-18 18:42:55
【问题描述】:

假设您正在尝试访问地图中嵌套较深的孩子,而您无法期望他们的父母在那里。示例:

Map awesomeMap = {
    "this":{
        "is":{
            "sometimes":"not here"
        }
    }
}

Map notAwesomeMap = {
    "this":{
        "haha":{
            "we":"switched"
        }
    }
}

当我访问notAwesomeMap['this']['is']['sometimes'] 时,它会返回一个错误,因为['this']['is']null,并且您无法查找null 的值['sometimes']

这很好,但我希望能够使用条件成员访问运算符...

notAwesomeMap['this']?.['is']?.['sometimes']

但这不起作用......

没有将所有内容都包装在 try 块中,有没有处理这些情况的好方法?

编辑:我试着玩弄这个,但我没有发现任何真正有启发性的东西,但也许这给了某人一个想法

void main() {
  Map nestedMap = {
    'this':{
      'is':{
        'sometimes':'here'
      }
    }
  };

  final mapResult = nestedMap['this'];
  print(mapResult); //returns {is: {sometimes: here}}

  final nullResult = nestedMap['this']['is an'];
  print(nullResult); // returns null


  final nullifiedResult = nullify(nestedMap['this']['is an']['error']);
  print(nullifiedResult); // returns error, but is this possible another way?

  final errorResult = nestedMap['this']['is an']['error'];
  print(errorResult); // returns error
}



nullify(object){
  try {
    final result = object;
    return result;
  }
  catch (e) {
    return null;
  }
}

【问题讨论】:

标签: dart


【解决方案1】:

你可以编写一个简单的函数来帮助你做你想做的事:

R lookup<R, K>(Map<K, dynamic> map, Iterable<K> keys, [R defaultTo]);

示例用法:

final result = lookup(inputMap, ['this', 'is', 'something']);

示例实现: https://dartpad.dartlang.org/1a937b2d8cdde68e6d6f14d216e4c291

void main() {
  var nestedMap = {
    'this':{
      'is':{
        'sometimes':'here'
      }
    }
  };

  print(lookup(nestedMap, ['this']));
  print(lookup(nestedMap, ['this', 'is']));
  print(lookup(nestedMap, ['this', 'is', 'sometimes']));
  print(lookup(nestedMap, ['this', 'is', 'error']));

  // Bail out on null:
  print(lookup(nestedMap, ['error'], 'Default Value'));
}

R lookup<R, K>(Map<K, dynamic> map, Iterable<K> keys, [R defaultTo]) {
  dynamic current = map;
  for (final key in keys) {
    if (current is Map<K, dynamic>) {
      current = current[key];
    } else {
      return defaultTo;
    }
  }
  return current as R;
}

【讨论】:

    【解决方案2】:

    我喜欢@matanlurey 的方法,但做了两处改变:

    1. 删除defaultTo,因为您仍然可以使用更具可读性的??
    2. 吞下类型转换错误。
    R lookup <R, K>(Map<K, dynamic> map, Iterable<K> keys) {
      dynamic current = map;
      for (final key in keys) {
        if (current is Map<K, dynamic>) {
          current = current[key];
        }
      }
      try{
        return current as R;
      } catch(e){
        // do nothing
      }
    }
    

    用法类似

    String someValue = lookup(nestedMap, ['some', 'value']) ?? 'Default Value';
    

    【讨论】:

      【解决方案3】:

      一种方法是

      final result = (((nestedMap ?? const {})['this'] ?? const {})['is an'] ?? const {})['error'];
      

      另见Null-aware operator with Maps

      【讨论】:

        猜你喜欢
        • 2022-12-09
        • 2011-05-03
        • 1970-01-01
        • 2018-06-20
        • 2011-11-03
        • 1970-01-01
        • 1970-01-01
        • 2014-07-13
        • 1970-01-01
        相关资源
        最近更新 更多