Arjun Mahar
Arjun Mahar

Reputation: 367

i want sum of numbers from a list and display it in a Text widget

This is my list and i want sum of unreadMsgs in Text widget. I cant figure out how can i get unreadMsgs from this list and add them. can anyone help how can i do?

List<UsersData> user = [

  UsersData(
    name: 'Zack Alex',
    msg: 'Im on my way.',
    status: '3 hours ago',
    dp: 'assets/Zack.jpg',
    seenMsgs: false,
    unreadMsgs: 12,
  ),

  UsersData(
    name: 'Ali sho',
    msg: 'Send an attachemnt',
    status: 'false',
    dp: 'assets/Ali.jpg',
    seenMsgs: false,
    unreadMsgs: 3
  ),

  UsersData(
    name: 'Marie',
    msg: 'Gud Morning',
    status: '23 seconds ago',
    dp: 'assets/Marie.jpg',
    seenMsgs: true,
    unreadMsgs: 6,
  ),
];

Upvotes: 0

Views: 1241

Answers (3)

SupposedlySam
SupposedlySam

Reputation: 685

Map and Fold

The most readable way to accomplish this is to do it in two parts. First, map over your list of userData (aka user) and extract the unreadMsgs. Second, add all of the values together using fold.

Fold vs Reduce

use fold instead of reduce to provide a default value in case your List is ever empty.

Example

View it on CodePen

final int unreadMsgCount =
    user
      .map((data) => data.unreadMsgs)
      .fold(0, (acc, curr) => acc + curr);

return Scaffold(
  body: Center(
    child: Text(
      '$unreadMsgCount',
      style: Theme.of(context).textTheme.headline4,
    ),
  ),
);

fold is probably the easiest to get tripped up on. The first argument of fold is the initialValue and the second argument is a callback function defining the work you want done.

In our case we want to do addition on our unreadMsgs. By convention you'll see acc or agg as the first argument in this callback, acc stands for accumulator and agg stands for aggregation or aggregator but you can just as easily name it prev for previous; curr stands for current.

map takes care of extracting your unreadMsgs and fold sums those values into the unreadMsgCount variable we defined.

Use string interpolation to cast the int as a String for your Text widget.

Upvotes: 3

timilehinjegede
timilehinjegede

Reputation: 14043

Try this: It works fine

class MyHomePage extends StatelessWidget {

  List<UsersData> user = [
    UsersData(
      name: 'Zack Alex',
      msg: 'Im on my way.',
      status: '3 hours ago',
      dp: 'assets/Zack.jpg',
      seenMsgs: false,
      unreadMsgs: 12,
    ),
    UsersData(
        name: 'Ali sho',
        msg: 'Send an attachemnt',
        status: 'false',
        dp: 'assets/Ali.jpg',
        seenMsgs: false,
        unreadMsgs: 3),
    UsersData(
      name: 'Marie',
      msg: 'Gud Morning',
      status: '23 seconds ago',
      dp: 'assets/Marie.jpg',
      seenMsgs: true,
      unreadMsgs: 6,
    ),
  ];

  // variable to hold sum of unread messages
  int sumOfUnreadMsgs = 0;

  @override
  Widget build(BuildContext context) {

    // use a for loop to loop through your list
    for (var person in user){
      // add all the messages here
      sumOfUnreadMsgs += person.unreadMsgs ;
    }

    return Scaffold(
      body: Center(
       // display sum of unread messages here
        child: Text('Sum of unread message is $sumOfUnreadMsgs'),
      ),
    );
  }
}

OUTPUT

enter image description here

Upvotes: 0

Sanjay Sharma
Sanjay Sharma

Reputation: 4035

You can make use of operator overloading here. Probably it's not the best way but one of the possible way.

class Item {
  Item({this.id, this.msg});
  String id;
  int msg;

  Item operator +(Item other) {
    return Item(id: "", msg: (this.msg + other.msg));
  }
}

void main() {
  List<Item> data = [
    new Item(id: "A1", msg: 100),
    new Item(id: "A2", msg: 200),
    new Item(id: "A2", msg: 350)
  ];
  print(data.reduce((curr, next) => curr + next).msg);
}

Upvotes: 0

Related Questions