Search code examples
flutterdartstatisticsmedian

Find the Median of a list<int> in Dart


I have a list of integers which contains times in milliseconds (ex. 1433, 834, 1020..). I need to calculate the Median. I developed the following code but the Median I get is completely wrong compared to the one I calculate in Excel. Any ideas? is there any Dart/flutter library I could use for statistics?

  /// Calculate median
  static int calculateMedian(TimeRecordNotifier timeRecordNotifier) {
    List<int> mList = List();
    timeRecordNotifier.timeRecords.forEach((element) {
      mList.add(element.partialTime);
    });

    //clone list
    List<int> clonedList = List();
    clonedList.addAll(mList);

    int median;
    //sort list
    clonedList.sort((a, b) => a.compareTo(b));

    if (clonedList.length == 1)
      median = mList[clonedList.length - 1];
    else if (clonedList.length % 2 == 1)
      median = mList[(((clonedList.length) / 2) - 1).round()];
    else {
      int lower = mList[((clonedList.length ~/ 2) - 1)];
      int upper = mList[(clonedList.length ~/ 2)];
      median = ((lower + upper) / 2.0).round();
    }

    return median;
  }

On the following dataset the expected median value is 901,5, however this algorithm gives me 461

131
144
203
206
241
401
415
427
439
439
452
455
456
469
471
471
483
483
491
495
495
502
505
512
521
522
523
547
551
561
610
727
745
777
790
793
892
911
924
943
957
977
978
989
992
1008
1024
1039
1070
1074
1092
1115
1139
1155
1159
1174
1176
1194
1203
1208
1227
1228
1248
1270
1271
1272
1273
1276
1284
1290
1294
1439
1740
1786

Solution

  • I refactored the code into this using NumDart implementation and now it works. thanks @MartinM for you comment!

    /// Calculate median
      static int calculateMedian(TimeRecordNotifier timeRecordNotifier) {
        List<int> mList = List();
        timeRecordNotifier.timeRecords.forEach((element) {
          mList.add(element.partialTime);
        });
    
        //clone list
        List<int> clonedList = List();
        clonedList.addAll(mList);
    
        //sort list
        clonedList.sort((a, b) => a.compareTo(b));
    
        int median;
    
        int middle = clonedList.length ~/ 2;
        if (clonedList.length % 2 == 1) {
          median = clonedList[middle];
        } else {
          median = ((clonedList[middle - 1] + clonedList[middle]) / 2.0).round();
        }
    
        return median;
      }