Find minimum or maximum value from Array

Browsing through the questions at the Adobe Flex forum again and came across one about having an issue with the Y-axis display on a dual-Y axis column/line chart. I’m not sure I gave the answer the poster was looking for, but my guess was that the minimum and maximum values for each LinearAxis was not set. You could set them to static values, but that wouldn’t be too useful. So, I did a quick search for some code to find the max value of an array and then modified it for AS3.

private function findMax(sourceArray:Array, sourceValue:String):Number {
	var maxNumber:Number = 0;
	for (var i:int = 0; i < sourceArray.length; i++) { 		var tmpNum:Number = new Number((sourceArray[i][sourceValue]).toString()); 		if(tmpNum > maxNumber) {
			maxNumber = sourceArray[i][sourceValue];
		}
	}

	return maxNumber;
}

private function findMin(sourceArray:Array, sourceValue:String, startMax:Number):Number {
	var minNumber:Number = startMax;
	for (var i:int = 0; i < sourceArray.length; i++) {
		var tmpNum:Number = new Number((sourceArray[i][sourceValue]).toString());
		if(tmpNum < minNumber) {
			minNumber = sourceArray[i][sourceValue];
		}
	}

	return minNumber;
}

— update —
There is apparently even an easier way of finding the minimum and maximum in an array of values using a Math function. However, you still have to split out the particular set of values from the overall array, which I don’t think there is a way to do.

Math.max(Array[]);
Math.min(Array[]));

It is pretty straight forward. Go through the array and find the value for a particular column, then check to see if it is smaller or larger than the previous stored value. The only difference between the two, is setting the starting high value for finding the minimum. So, when using these functions, you should find the maximum first and use that value as the startMax in order to find the minimum. This is who it was used in the LinearAxis code.

// VERTICAL AXIS
var verticalAxisLeft:LinearAxis = new LinearAxis();
verticalAxisLeft.autoAdjust = true;
verticalAxisLeft.maximum = Math.ceil(findMax(SMITH.source, "open"));
verticalAxisLeft.minimum = Math.ceil(findMin(SMITH.source, "open", verticalAxisLeft.maximum));

var verticalAxisRight:LinearAxis = new LinearAxis();
verticalAxisRight.autoAdjust = true;
verticalAxisRight.maximum = Math.ceil(findMax(DECKER.source, "close"));
verticalAxisRight.minimum =  Math.ceil(findMin(DECKER.source, "close", verticalAxisRight.maximum));

However, using the right Array, that has higher values than the left, will cause some issues. It is probably best to either use 0 or the smaller minimum value of the two arrays.

ArrayCollection SortOn before a Sort

I have a display screen that shows a list of items waiting to be acknowledged by technicians. If the page isn’t acknowledged, then the page is escalated up to the next level. The display uses a DataGrid and when the number of items exceeds the displayable rows on the DataGrid, it uses pagination functions to create multiple pages for viewing the other items. When an ArrayCollection is sliced for each page, it causes an issue with sorting. When the data was sorted by level and datetime, it would only sort on the current slice of data, even if I sorted the ArrayCollection before slicing the data. It didn’t seem to matter that I was creating a new ArrayCollection when I was doing the slice, the result was the same, until I figured out the obvious solution.

				acMainArray.source.sortOn(["MessageLevel"], [Array.DESCENDING | Array.NUMERIC]);
				acMainArray.refresh();

				// Sort the Pages based on MessageLevel and PageReceivedDateTime
				acPagnationArray= new ArrayCollection(acMainArray.source);
				
				// Split the main ArrayCollection based on the number of pages and current paging index.
				acPagnationArray= new ArrayCollection(acPagnationArray.source.slice((pagingPageIndex * pagingPageSize),(pagingPageIndex * pagingPageSize) + pagingPageSize));
				acPagnationArray.sort = pageSort;
				acPagnationArray.refresh();

The easy step is to sortOn the original ArrayCollection on the source. Then pass the source into the new ArrayCollection that will be used to create the pages. I do a sort on the sliced ArrayCollection, just to be sure that both the level and DateTime stamp are being sorted. However, I can just do the complete sort on the two items, with a DESCENDING NUMERIC sort on the first and skip the sort after the slice.

acPagingEscalation.source.sortOn(["MessageLevel", "PageReceivedDateTime"], [Array.DESCENDING | Array.NUMERIC, Array.DESCENDING]);
acPagingEscalation.refresh();

It seems that most times in programming, the solution is so simple that you wonder why you didn’t find it earlier.