In AS3 I had a function to find the Median value, however when trying to translate it in Haxe, it throws errors, it seems to be related to the Array sort() function but I am not exactly sure how to fix this,
// test case, should return 3
var myarr2:Array<Float> = new Array();
myarr2 = [3, 5, 4, 4, 1, 1, 2, 3];
trace( tMath.Median(myarr2) );
// functions
public inline function IsEven(value:Float):Bool {
return (value % 2) > 0.5? false : true;
};
public inline function Median(numbers:Array<Float>):Float {
var median:Float = 0;
var numsLen:Float = numbers.length;
numbers.sort();
if (this.IsEven(numsLen)) { // is even
// average of two middle numbers
median = (numbers[numsLen / 2 - 1] + numbers[numsLen / 2]) / 2;
} else { // is odd
// middle number only
median = numbers[(numsLen - 1) / 2];
}
return median;
};
In Haxe, the comparison function is not optional. To put the numbers in ascending order, you have to do this:
numbers.sort(function(a:Float, b:Float):Int {
return b == a ? 0 : (b > a ? -1 : 1);
});
To make this easier in the future, you might want to save a copy of this class. Then when you need to sort, you can just pick one of those functions.
2 Likes
Ahh I see, I expected these to come as standard and be optional like in AS3, thank you, those will come in handy.
I was getting errors after that though, that the array indexes should be Int instead of Floats, so I used Std.int() and seems the function works though. Was that a safe thing to do?
Full function:
public inline function Median(numbers:Array<Float>):Float {
var median:Float = 0.0;
var numsLen:Float = numbers.length;
numbers.sort(function(a:Float, b:Float):Int { return b == a ? 0 : (b > a ? -1 : 1); });
if (this.IsEven(numsLen)) { // is even
// average of two middle numbers
median = (numbers[Std.int(numsLen / 2 - 1)] + numbers[Std.int(numsLen / 2)]) / 2;
} else { // is odd
// middle number only
median = numbers[Std.int((numsLen - 1) / 2)];
}
return median;
};
Yes, you need to convert to an integer, and yes, Std.int()
is one correct way to do that. In another situation, you might use Math.round()
, Math.floor()
, or Math.ceil()
instead. (These functions also convert floats to ints, but they use different rounding rules.)