Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

I am trying to get the average per object in a list

I am writing some code where I have a list that gets added to alot. Each time it gets added it has 2 values: a string and an integer.
I would like that it takes all of that data and that it gets the average of the integer per string, and puts that in a list.

Example:

void main() {
  List people = [];
  
  people.add({'person': 'mike', 'score': 32});  
  people.add({'person': 'david', 'score': 29});  
  people.add({'person': 'mike', 'score': 28});  
  people.add({'person': 'kim', 'score': 34});  
  people.add({'person': 'david', 'score': 31});  
  people.add({'person': 'david', 'score': 31});  
  people.add({'person': 'kim', 'score': 32});
  
  print(people);
}

Above you can see the list people has a few different persons and scores. I would like it that when I print(people) it shows a list like:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

{['person': 'mike', 'score': 30], ['person': 'david', 'score': 30], ['person': 'kim', 'score': 33]}

As you can see above the scores are the average lists of the full list, and doubles get rounded to ints.

Is there a way to do this?

>Solution :

It requires some mapping. First collect all scores per person in a Map. Then recreate the entries in the desired format. This can be done a bit more compact but I think this makes it easier to read.

Note that this implementation returns a double as the score instead of an int. If that’s not desired, you can add a .round() to the calculation of the average. Or as Tray Denney suggested, use the ~/ operator which divides and returns an int by ignoring the decimals.

void main() {
  List people = [];

  people.add({'person': 'mike', 'score': 32});
  people.add({'person': 'david', 'score': 29});
  people.add({'person': 'mike', 'score': 28});
  people.add({'person': 'kim', 'score': 34});
  people.add({'person': 'david', 'score': 31});
  people.add({'person': 'david', 'score': 31});
  people.add({'person': 'kim', 'score': 32});

  final scoresPerPerson = people.fold<Map<String, List<int>>>(
    {}, // initial empty map
    (map, person) {
      final name = person['person'];
      map.update(
        name,
        (scores) => [...scores, person['score']], // update the existing list of scores
        ifAbsent: () => [person['score']], // create a new list of scores for this person
      );
      return map;
    },
  );

  final averages =
      scoresPerPerson.entries.map((MapEntry<String, List<int>> item) {
    return {
      'person': item.key,
      'score': item.value.reduce((a, b) => a + b) /
          item.value.length, // calculate the average of all scores
    };
  });

  print(averages);
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading