Home > database >  Flutter: Maintain multi-dimensional List data type with JSON data
Flutter: Maintain multi-dimensional List data type with JSON data

Time:06-01

I wish to load JSON data of the type of a 2-dimensional array of doubles.
If I attempt to do that via json.encode the type is lost.

So, the following fails:

import 'dart:convert';
main() {
  var x = [[0.0,0.0]];
  print(x.runtimeType);               // List<List<double>>
  x = json.decode( json.encode (x) ); // this line fails
}

With the error message:

type 'List<dynamic>' is not a subtype of type 'List<List<double>>'

How can I maintain the type of List<List<double>> when loading in JSON data?


I've tried the following:

x = json.decode( json.encode (x) ) as List<List<double>>;

type 'List<dynamic>' is not a subtype of type 'List<List<double>>' in type cast

x = List<List<double>>.from(json.decode( json.encode (x) ));

type 'List<dynamic>' is not a subtype of type 'List<double>'

CodePudding user response:

While my original post was for a 2D array, my actual problem was with a 4D array.

I ended up with making a custom class to process these :

class JsonArrayConversion {

  static List<double> convertJson(List<dynamic> json) {
    return json.map((e) => e as double).toList();  
  }

  static List<List<double>> convertJson2(List<dynamic> json) {
    return json.map((e) {
      if (e is List<dynamic>) {
        return convertJson(e);
      } else {
        return [] as List<double>;
      }    
    }).toList();
  }

  static List<List<List<double>>> convertJson3(List<dynamic> json) {
    return json.map((e) {
      if (e is List<dynamic>) {
        return convertJson2(e);
      } else {
        return [] as List<List<double>>;
      }    
    }).toList();
  }

  static List<List<List<List<double>>>> convertJson4(List<dynamic> json) {
    return json.map((e) {
      if (e is List<dynamic>) {
        return convertJson3(e);
      } else {
        return [] as List<List<List<double>>>;
      }    
    }).toList();
  }

}

And for the example in the original post, the solution becomes:

x = JsonArrayConversion.convertJson2( json.decode( json.encode (x) ) );

Clunky, but it works.

CodePudding user response:

Try this (from https://app.quicktype.io/)

import 'dart:convert';

class NumbersList {
    NumbersList({
        required this.numbers,
    });

    List<List<double>>? numbers;

    factory NumbersList.fromJson(String str) => NumbersList.fromMap(json.decode(str));

    String toJson() => json.encode(toMap());

    factory NumbersList.fromMap(Map<String, dynamic> json) => NumbersList(
        numbers: json["numbers"] == null ? null : List<List<double>>.from(json["numbers"].map((x) => List<double>.from(x.map((x) => x.toDouble())))),
    );

    Map<String, dynamic> toMap() => {
        "numbers": numbers == null ? null : List<dynamic>.from(numbers!.map((x) => List<dynamic>.from(x.map((x) => x)))),
    };
}

Use:

var jsonString = '{"numbers": [[1.0, 1, 2],[2.5, 5, 6]]}'; final numbersList = NumbersList.fromJson(jsonString); print(numbersList.toJson());

Or simply:

 var str = "[[1.0, 1, 2],[2.5, 5, 6]]";
 var numbers = json.decode(str);
 var n = List<List<double>>.from(numbers.map((x) => List<double>.from(x.map((x) => x.toDouble()))))
  • Related