95

How do you get the min and max values of a List in Dart.

[1, 2, 3, 4, 5].min //returns 1
[1, 2, 3, 4, 5].max //returns 5

I'm sure I could a) write a short function or b) copy then sort the list and select the last value,

but I'm looking to see if there is a more native solution if there is any.

basheps
  • 8,714
  • 9
  • 35
  • 45

7 Answers7

174

Assuming the list is not empty you can use Iterable.reduce :

import 'dart:math';

main(){
  print([1,2,8,6].reduce(max)); // 8
  print([1,2,8,6].reduce(min)); // 1
}
ThinkDigital
  • 2,681
  • 3
  • 23
  • 34
Alexandre Ardhuin
  • 62,400
  • 12
  • 142
  • 126
45

If you don't want to import dart: math and still wants to use reduce:

main() {
  List list = [2,8,1,6]; // List should not be empty.
  print(list.reduce((curr, next) => curr > next? curr: next)); // 8 --> Max
  print(list.reduce((curr, next) => curr < next? curr: next)); // 1 --> Min
}
kk.
  • 3,288
  • 11
  • 33
  • 60
  • Why would one seriously prefer this approach? – Mateus Felipe Dec 19 '19 at 20:54
  • @MateusFelipe You can pass this as a Function, where as with math.max or min I ran into some trouble. – onesiumus Jan 26 '20 at 04:01
  • Well, then it would be a good idea providing the specific use-case of your approach, as it seems to be a very edge case. – Mateus Felipe Jan 27 '20 at 08:51
  • 18
    This actually is a useful comment. Whenever the list is List of Objects rather than List of (String, Number) we can't directly use dart:math. We have to do something like "curr.id < next.id" etc. – Kavinda Jayakody Feb 18 '20 at 13:46
  • 1
    Exactly, it is totally useful. For example, I used this for DateTime: `dates.reduce((current, next) => current.compareTo(next) > 0 ? current : next)` Closest thing to LINQ-like syntax. – jnt Jun 09 '20 at 14:44
  • @KavindaJayakody You can do this using myList.map((e) => e.myNumber).reduce(max) – kozenka Mar 26 '21 at 21:11
27

You can now achieve this with an extension as of Dart 2.6:

import 'dart:math';

void main() {
  [1, 2, 3, 4, 5].min; // returns 1
  [1, 2, 3, 4, 5].max; // returns 5
}

extension FancyIterable on Iterable<int> {
  int get max => reduce(math.max);

  int get min => reduce(math.min);
}
creativecreatorormaybenot
  • 91,704
  • 51
  • 240
  • 358
8

An example to get Min/Max value using reduce based on condition for a list of Map objects

Map studentA = {
  'Name': 'John',
  'Marks': 85
};

Map studentB = {
  'Name': 'Peter',
  'Marks': 70
};

List<Map> students = [studentA, studentB];

// Get student having maximum mark from the list

Map studentWithMaxMarks = students.reduce((a, b) {
    if (a["Marks"] > b["Marks"])
        return a;
    else
        return b;
});


// Get student having minimum mark from the list (one liner)

Map studentWithMinMarks = students.reduce((a, b) => a["Marks"] < b["Marks"] ? a : b);

Another example to get Min/Max value using reduce based on condition for a list of class objects

class Student {
    final String Name;
    final int Marks;

    Student(this.Name, this.Marks);
}

final studentA = Student('John', 85);
final studentB = Student('Peter', 70);

List<Student> students = [studentA, studentB];

// Get student having minimum marks from the list

Student studentWithMinMarks = students.reduce((a, b) => a.Marks < b.Marks ? a : b);
Abdul Saleem
  • 9,221
  • 4
  • 41
  • 41
4

If your list is empty, reduce will throw an error.

You can use fold instead of reduce.

// nan compare to any number will return false
final initialValue = number.nan;
// max
values.fold(initialValue, (previousValue, element) => element.value > previousValue ? element.value : previousValue);
// min
values.fold(initialValue, (previousValue, element) => element.value < previousValue ? element.value : previousValue);

It can also use to calculate sum.

final initialValue = 0;
values.fold(initialValue, (previousValue, element) => element.value + previousValue);

Although fold is not cleaner than reduce for getting min/max, it is still a powerful method to do more flexible actions.

呂學洲
  • 892
  • 5
  • 15
2

For empty lists: This will return 0 if list is empty, the max value otherwise.

  List<int> x = [ ];  
  print(x.isEmpty ? 0 : x.reduce(max)); //prints 0

  List<int> x = [1,32,5];  
  print(x.isEmpty ? 0 : x.reduce(max)); //prints 32
lenz
  • 1,724
  • 12
  • 23
2
int minF() {
  final mass = [1, 2, 0, 3, 5];
  mass.sort();
  
  return mass[0];
}
Kley
  • 73
  • 1
  • 8