function collapseArray(array, newVal, newPad, opts, atLeastAsExtreme) {
    var tozero = opts.tozero;
    var extrapad = opts.extrapad;
    var includeThis = true;

    for(var j = 0; j < array.length && includeThis; j++) {
        var v = array[j];
        if(atLeastAsExtreme(v.val, newVal) && v.pad >= newPad && (v.extrapad || !extrapad)) {
            includeThis = false;
            break;
        } else if(atLeastAsExtreme(newVal, v.val) && v.pad <= newPad && (extrapad || !v.extrapad)) {
            array.splice(j, 1);
            j--;
        }
    }
    if(includeThis) {
        var clipAtZero = (tozero && newVal === 0);
        array.push({
            val: newVal,
            pad: clipAtZero ? 0 : newPad,
            extrapad: clipAtZero ? false : extrapad
        });
    }
}
collapseArray

Takes items from 'array' and compares them to 'newVal', 'newPad'.

@param {array} array:
 current set of min or max extremes
@param {number} newVal:
 new value to compare against
@param {number} newPad:
 pad value associated with 'newVal'
@param {object} opts:
 - tozero {boolean}
 - extrapad {number}
@param {function} atLeastAsExtreme:
 comparison function, use
 - lessOrEqual for min 'array' and
 - greaterOrEqual for max 'array'

In practice, 'array' is either
 - 'extremes[ax._id].min' or
 - 'extremes[ax._id].max
 found in traces and layout items that affect autorange.

Since we don't yet know the relationship between pixels and values
(that's what we're trying to figure out!) AND we don't yet know how
many pixels `extrapad` represents (it's going to be 5% of the length,
but we don't want to have to redo calc just because length changed)
two point must satisfy three criteria simultaneously for one to supersede the other:
 - at least as extreme a `val`
 - at least as big a `pad`
 - an unpadded point cannot supersede a padded point, but any other combination can

Then:
- If the item supersedes the new point, set includeThis false
- If the new pt supersedes the item, delete it from 'array'