Devima
Devima

Reputation: 1566

Get smallest and highest number to the right and left to my value

Please let me know if there is a faster, more elegant way to get this result:
I have an array of numbers, and once set a value i should get smallest and highest number to the right and left to my value.

For example if I have: [1,2,3,4,6,7,8,9] and a value is 5,
my numbers will be:1, 4,6,9
if value is 4
my numbers will be 1,4,4,9
My horrible code is:

var arr = [1, 8, 2, 3, 9, 5, 4, 6, 7];
var result1 = [];
var result2 = [];
var goal = 5;
for (a = 0; a < arr.length; a++) {
    if (arr[a] < goal) {
        result1.push(arr[a])
    } else if (arr[a] === goal) {
        result1.push(arr[a]);
        result2.push(arr[a]);
    } else {
        result2.push(arr[a]);
    }
};
var count1 = result1[0];
for (x = 0; x < result1.length; x++) {
    if (result1[x] < count1) {
        count1 = result1[x]
    }
};
var count11 = result1[0];
for (xx = 0; xx < result1.length; xx++) {
    if (result1[xx] > count11) {
        count11 = result1[xx]
    }
};
var count2 = result2[0];
for (y = 0; y < result2.length; y++) {
    if (result2[y] > count2) {
        count2 = result2[y]
    }
};
var count22 = result2[0];
for (yy = 0; yy < result2.length; yy++) {
    if (result2[yy] < count22) {
        count22 = result2[yy]
    }
};
console.log(count1 + ' ' + count11 + ' ' + count22 + ' ' + count2)

Upvotes: 0

Views: 97

Answers (4)

David W
David W

Reputation: 10184

EDIT

Although I realize the question has been answered and another response selected, I at least wanted to update my code to a tested version. FWIW, it works, and does not rely on nor assume a sorted array.

function minmax(valueArray, targetValue) {

var i = 0;
var minBelow;
var maxBelow;
var minAbove;
var maxAbove;

while (i < valueArray.length) {
    var currentValue = valueArray[i];

    if (currentValue < targetValue) {
        if (currentValue < minBelow || !minBelow) {
            minBelow = currentValue;
        }
        if (currentValue > maxBelow || !maxBelow) {
            maxBelow = currentValue;
        }
    }
    if (currentValue > targetValue) {
        if (currentValue < minAbove || !minAbove) {
            minAbove = currentValue;
        }
        if (currentValue > maxAbove || !maxAbove) {
            maxAbove = currentValue;
        }

    }
    i++;
}

return {
    minBelow: minBelow,
    maxBelow: maxBelow,
    minAbove: minAbove,
    maxAbove: maxAbove
};

}

function test() {
    alert('In test');
    var foo = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    var bar = minmax(foo, 5);
    alert(bar.minBelow + ","+ bar.maxBelow + "," + bar.minAbove + "," + bar.maxAbove);
}

Upvotes: 0

Oybek
Oybek

Reputation: 7243

Well I came up with the following solution. Considering that array is always sorted

function GetVals(arr, pivot){
    return arr.reduce(function(t,v,i,arr){ 
        if (v < pivot) {
            if (typeof t.LMin == "undefined" || t.LMin > v)
                t.LMin = v;
            if (typeof t.LMax == "undefined" || t.LMax < v)
                t.LMax = v;
        } else if (v > pivot) {
            if (typeof t.RMin == "undefined" || t.RMin > v)
                t.RMin = v;
            if (typeof t.RMax == "undefined" || t.RMax < v)
                t.RMax = v;
        }
        return t;
    }, {});
}

The returned result will have 4 properties, LMin LMax for left min and max and RMin RMax for right min maxes respectively.

if LMin and LMax are equal, this means there is only 1 value from the left (the same rule for the right)

if LMin and LMax are undefined, this means that there are no values from the left less than pivot.

Upvotes: 0

Bergi
Bergi

Reputation: 664528

You can simplify your code a lot by using a few mighty methods: Array::filter and Math.min/max:

var arr = [1, 8, 2, 3, 9, 5, 4, 6, 7];
var goal = 5;

var result1 = arr.filter(function(x) { return x <= goal });
var result2 = arr.filter(function(x) { return x >= goal });
var count1  = Math.min.apply(Math, result1);
var count11 = Math.max.apply(Math, result1);
var count2  = Math.min.apply(Math, result2);
var count22 = Math.max.apply(Math, result2);

Upvotes: 1

thefourtheye
thefourtheye

Reputation: 239473

Assuming the array is sorted always,

var array = [1, 2, 3, 4, 6, 7, 8, 9],
    number = 5,
    pivot, small, large;

for (var i = 0, len = array.length; i < len; i += 1) {
    if (array[i] >= number) {
        pivot = i;
        break;
    }
}

if (pivot > 0) {
    small = [array[0], array[pivot - 1]];
    large = [array[pivot], array[len - 1]];
    console.log(small, large);
} else {
    console.log("Not possible");
}

Upvotes: 0

Related Questions