Kel
Kel

Reputation: 463

How to sum integer from this Iterate data

I have a JSON like this

[
  {
    "name": "A",
    "forX": [
      {
        "amount": 1
      },
            {
        "amount": 2
      }
    ],
    "forY": [
      {
        "amount": 3
      },
            {
        "amount": 4
      }
    ]
  },
  {
    "name": "B",
    "forX": [
      {
        "amount": 5
      }
    ],
    "forY": null
  }
]

How can I get the sum of the results forX.amount and forY.amount for each name?

(the result to display will be A -> forX = 3 forY = 7; B-> forX = 5)

Full code:

import 'package:flutter/material.dart';
import 'dart:convert';

List<Json> jsonFromJson(String str) => List<Json>.from(json.decode(str).map((x) => Json.fromJson(x)));

String jsonToJson(List<Json> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class Json {
  Json({this.name, this.forX, this.forY});

  String name;
  List<ForX> forX;
  List<ForY> forY;

  factory Json.fromJson(Map<String, dynamic> json) => Json(
        name: json["name"] == null ? null : json["name"],
        forX: json["forX"] == null ? null : List<ForX>.from(json["forX"].map((x) => ForX.fromJson(x))),
        forY: json["forY"] == null ? null : List<ForY>.from(json["forY"].map((x) => ForY.fromJson(x))),
      );

  Map<String, dynamic> toJson() => {
        "name": name == null ? null : name,
        "forX": forX == null ? null : List<dynamic>.from(forX.map((x) => x.toJson())),
        "forY": forY == null ? null : List<dynamic>.from(forY.map((x) => x.toJson())),
      };
}

class ForY {
  ForY({this.amount});
  int amount;
  factory ForY.fromJson(Map<String, dynamic> json) => ForY(amount: json["amount"] == null ? null : json["amount"]);
  Map<String, dynamic> toJson() => {"amount": amount == null ? null : amount};
}

class ForX {
  ForX({this.amount});
  int amount;
  factory ForX.fromJson(Map<String, dynamic> json) => ForX(amount: json["amount"] == null ? null : json["amount"]);
  Map<String, dynamic> toJson() => {"amount": amount == null ? null : amount};
}

class JsonServices {
  static Future<List<Json>> getData() {
    String jsonString = '''
[
  {
    "name": "A",
    "forX": [
      {
        "amount": 1
      },
            {
        "amount": 2
      }
    ],
    "forY": [
      {
        "amount": 3
      },
            {
        "amount": 4
      }
    ]
  },
  {
    "name": "B",
    "forX": [
      {
        "amount": 5
      }
    ],
    "forY": null
  }
]
    ''';

    return Future.value(jsonFromJson(jsonString));
  }
}

class Sum extends StatefulWidget {
  @override
  _SumState createState() => _SumState();
}

class _SumState extends State<Sum> {
  List<Json> _json = [];
  @override
  void initState() {
    super.initState();
    setState(() {
      JsonServices.getData().then((data) {
        setState(() {
          _json = data;
        });
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        for (var j in _json)
          Row(
            children: [
              Expanded(child: Text(j.name)),
              for (int i = 0; i < j.forX.length; i++)
                if (j.forX[i].amount != null) Text('For X: ${j.forX[i].amount}'),
              if (j.forY != null)
                for (int i = 0; i < j.forY.length; i++)
                  if (j.forY != null)
                    Text(
                      'For Y: ${j.forY[i].amount}',
                    )
            ],
          ),
      ],
    );
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(),
        body: Sum(),
      ),
    );
  }
}

Upvotes: 2

Views: 148

Answers (1)

Mohammad Hammadi
Mohammad Hammadi

Reputation: 793

You can add a method in the Json class which does the calculation for each Item in json data as follow :

check getSummationString() method

class Json {
  Json({this.name, this.forX, this.forY});

  String name;
  List<ForX> forX;
  List<ForY> forY;

  factory Json.fromJson(Map<String, dynamic> json) => Json(
    name: json["name"] == null ? null : json["name"],
    forX: json["forX"] == null
        ? null
        : List<ForX>.from(json["forX"].map((x) => ForX.fromJson(x))),
    forY: json["forY"] == null
        ? null
        : List<ForY>.from(json["forY"].map((x) => ForY.fromJson(x))),
  );

  Map<String, dynamic> toJson() => {
    "name": name == null ? null : name,
    "forX": forX == null
        ? null
        : List<dynamic>.from(forX.map((x) => x.toJson())),
    "forY": forY == null
        ? null
        : List<dynamic>.from(forY.map((x) => x.toJson())),
  };

  String getSummationString() {
    double forXSummation = 0;
    double forYSummation = 0;
    if (this.forX != null) {
      this.forX.forEach((element) {
        forXSummation += element.amount;
      });
    }

    if (this.forY != null) {
      this.forY.forEach((element) {
        forYSummation += element.amount;
      });
    }

    return '${this.name} -> forX = $forXSummation, forY = $forYSummation;';
  }
}

Then you can use ListView to show the data for each Name as follow:

@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Expanded(
          child: ListView.builder(
            itemCount: _json.length,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text(_json[index].getSummationString()),
              );
            },
          ),
        ),
      ),
    );
  }

result as follow:

enter image description here

It is better to separate logic from ui.

Upvotes: 1

Related Questions