地图儿童有条件的成员访问权限?

时间:2018-07-18 18:42:55

标签: dart

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

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

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

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

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

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;
  }
}

3 个答案:

答案 0 :(得分:2)

一种方法是

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

另请参阅Null-aware operator with Maps

答案 1 :(得分:0)

您可以编写一个简单的函数来帮助您完成所需的工作:

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 :(得分:0)

我喜欢@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';