Search code examples
javascriptjqueryarraysobject-literal

How to I compare an input value to reference values in an object literal?


I'd like to compare a user input value, to a set of values arranged in an object literal. The user will input two values, a reference variable wk and a number. Those need to be cross referenced in the object literal, but I can't seem to figure out the logic to do so?

The object literal is constructed as follows:

var reference = {
   wk31: {
        _90th: '758',
        _75th: '683',
        _50th: '600',
        _25th: '516',
        _10th: '441'
    },
    wk32: {
        _90th: '815',
        _75th: '734',
        _50th: '644',
        _25th: '554',
        _10th: '472'
    },
    wk33: {
        _90th: '870',
        _75th: '783',
        _50th: '687',
        _25th: '590',
        _10th: '503'
    }
}

For example, if wk = 32 & number = 755, then I'd like to make the user aware that their number is between the 75th and 90th percentile for that wk value.

Any help is appreciated. Thanks.


Solution

  • From what is written here and here, it appears you cannot rely on the order of the array returned by Object.keys() and the order in which the for ... in loop will enumerate over an object's properties.

    Instead, rearrange the data into something that is more usable.

    First, get the correct object for the wk value using the following:

    var wkObj = reference['wk' + wk];
    

    Then rearrange those values using:

    var percentiles = $.map(wkObj, function(value, key) {
        return { number: Number(value), percentile: key.substr(1) };
    }).sort(function(a, b) { return a.number - b.number; });
    

    This creates an array of objects, where each object has two properties: (1) number, which is a number, and (2) percentile, which is a string. The array is sorted by the number values in ascending order.

    For example, the percentiles array would look like the following for wk = 32:

    [
        { number: 472, percentile: '10th' },
        { number: 554, percentile: '25th' },
        { number: 644, percentile: '50th' },
        { number: 734, percentile: '75th' },
        { number: 815, percentile: '90th' }
    ]
    

    Now the number values are numbers, not strings, and you can safely loop through the array in the desired order.

    var upperIndex = -1;
    $.each(percentiles, function(i, obj) {
        if (obj.number > number) {
            upperIndex = i;
            return false;
        }
    });
    

    Here is a jsfiddle that shows the code above in use.