2012-08-22 3 views
4

J'ai un tableau JavaScript et une variable comme ça;Sélection du plus grand nombre plus petit qu'une variable dans le tableau

var a = [0, 1200, 3260, 9430, 13220], 
    b = 4500; 

Quelle serait la manière la plus intelligente de sélectionner la plus grande valeur dans la matrice qui est toujours inférieure ou égale à la variable? Dans cet exemple, je dois sélectionner 3260.

Je pourrais faire quelque chose comme ceci;

$.each(a, function(i){ 
    if(a[i] <= b && a[i+1] > b){ 
     var c = a[i]; 
     return false; 
    } 
}); 

Mais je pense que cela pourrait ne pas fonctionner si la valeur de tableau sélectionnée est la dernière. Sans oublier, pour moi, ça ressemble à beaucoup de code pour quelque chose de plutôt simple.

Existe-t-il une façon plus intelligente/moins verbeuse de réaliser ce que je cherche?

(et oui, je sais que je ne devrais pas avoir utilisé une boucle jQuery pour cela, mais je suis paresseux lorsque vous tapez des exemples)

+0

Si ce tableau est 'toujours a' commande, vous pouvez effectuer [recherche binaire ] (http://en.wikipedia.org/wiki/Binary_search_algorithm) sur ce tableau. Mais si le tableau est de petite taille, alors vous pouvez le parcourir linéairement ... ce serait un gain de temps négligeable. – Stano

Répondre

7

Une autre façon pour vous c'est à travers une combinaison de filtrage de tableau et apply(), ce qui est une approche très lisible. L'appel à filter() renvoie juste un tableau d'éléments dans un qui ne satisfont pas la fonction de prédicat, puis applique() appelle Math.max avec chaque élément comme argument.

var a = [1, 2, 3, 4, 5]; 
var b = 4; 
var result = Math.max.apply(Math, a.filter(function(x){return x <= b})); 

Le résultat sera égal à 4.

+0

Doit aimer les solutions one-liner, et celui-ci semble fonctionner! Merci! –

3
var max = Number.MIN_VALUE; 
for (var i = 0; i < a.length; i++) { 
    if (a[i] <= b && a[i] > max) { 
    max = a[i]; 
    } 
} 

Je pense que l'approche ci-dessus est assez simple, lisible, et pas très verbeux. Une alternative serait d'utiliser reduce, comme ceci:

var max = a.reduce(function (i, j) { return j <= b ? Math.max(i, j) : i }, Number.MIN_VALUE); 
1
var closest = null; 
$.each(a, function() { 
    if (closest == null || Math.abs(this - b) < Math.abs(closest - b)) { 
     closest = this; 
    } 
}); 

Une variante jQuery si cela pour une raison quelconque serait souhaitable.

2

Le tableau est-il toujours trié? Dans ce cas, vous pouvez optimiser votre code le long de ces lignes (vous pouvez vérifier les index, je ne l'ai pas vérifié le code):

var beginning = 0; 
var end = a.length; 
while ((end-beginning)>1) { 
    var currentIndex = Math.floor((beginning+end)/2);; 
    if (a[currentIndex] < b) { 
     beginning = currentIndex; 
    } else if (a[currentIndex] > b){ 
     end = currentIndex; 
    } else { 
     beginning=end=currentIndex; 
    } 
} 
var max = a[beginning]; 
+0

@Stano La modification était trop mineure. un commentaire est suffisant. Le P devrait prendre les mesures pour améliorer la réponse et le PO pour lire les commentaires –

+0

Mes excuses, faites vos modifications. –

+0

J'ai ajouté les modifications que vous avez suggérées, Stano. Merci pour ça! – Stilltorik

1

Après devrait faire:

function getHigh(arr, max){ 
    var c; 
    for(var i = 0, len=arr.length; i<len; i++){ 
    if(a[i] <= b) c=a[i]; 
    else return c; 
    } 
    return false; 
}

2

grep() de jQuery

var a = [0, 1200, 3260, 9430, 13220], 
b = 4500; 
var c= Math.max.apply(Math,$.grep(a,function(n){return n<=b})); 
document.write(c) 

WORKING DEMO

Questions connexes