Search code examples
flutterdartfolddart-null-safety

Dart fold with null safety


I have the following code that sums cash for people with the same name using list fold.

void main() { 
 List<Map<String,dynamic>> people = [{'name': 'Jim', 'cash':44.86},{'name': 'Jim', 'cash':40.55},{'name': 'Bob', 'cash':10.99},{'name': 'Bob', 'cash':10.99}];
  Map resultAmount = people.fold<Map<String, num>>({}, (totalMap, element) {
    final String key = element['name'];
      if (totalMap[key] == null) totalMap[key] = 0;
      totalMap[key] += element['cash'].toDouble();
      return totalMap;
    });
  print(resultAmount);
}

prints:

{Jim: 85.41, Bob: 21.98}

How can I get it to work with null-safety?


Solution

  • You can simplify the line

    if (totalMap[key] == null) totalMap[key] = 0;
    

    by just using the ??= operator.

    Then you'll need to rework the totalMap[key] increment to handle null-safety a bit better as Dart's static analysis isn't quite that smart.

    void main() { 
     List<Map<String,dynamic>> people = [{'name': 'Jim', 'cash':44.86},{'name': 'Jim', 'cash':40.55},{'name': 'Bob', 'cash':10.99},{'name': 'Bob', 'cash':10.99}];
      Map<String, num> resultAmount = people.fold<Map<String, num>>({}, (totalMap, element) {
        final String key = element['name'];
        totalMap[key] ??= 0;
        totalMap[key] = element['cash'].toDouble() + totalMap[key];
        return totalMap;
      });
      print(resultAmount);
    }
    

    Or, perhaps a more elegant solution, would be to use a temp variable:

    void main() { 
     List<Map<String,dynamic>> people = [{'name': 'Jim', 'cash':44.86},{'name': 'Jim', 'cash':40.55},{'name': 'Bob', 'cash':10.99},{'name': 'Bob', 'cash':10.99}];
      Map<String, num> resultAmount = people.fold<Map<String, num>>({}, (totalMap, element) {
        final String key = element['name'];
        
        double tmp = totalMap[key]?.toDouble() ?? 0.0;
        tmp += element['cash'].toDouble();
        
        totalMap[key] = tmp;
        return totalMap;
      });
      print(resultAmount);
    }