2013-03-18 2 views
15

je besoin d'un filtre jQuery/carte/chaque fonction du type de vérifier si tous les éléments satisfont à une condition:Vérifiez si tous les éléments satisfont à une condition

function areAllValid(inputs){ 
    return $.someFunction(inputs, function(input) { return input.length > 0; }); 
} 

Si toutes les entrées ont une longueur> 0 someFunction doit retourner vrai. Quelque chose comme ça dans jQuery?

+1

I ne pense pas que jQuery a ça. Underscore.js a '$ .every()'. Il devrait être simple à implémenter dans jQuery en utilisant '$ .filter'. – Barmar

+0

Notez, si vous pouvez trouver un moyen de décrire votre condition comme un sélecteur, alors vous pouvez vérifier le nombre d'éléments dans la collection 'inputs.remove ('[value = ...]'). Length == 0' Quelque chose le long des lignes d'un "sélecteur de valeur non vide": http://stackoverflow.com/questions/10641258/jquery-select-data-attributes-that-arent-empty – AaronLS

+0

@Barmar, chaque() est exactement ce dont j'ai besoin et coïncidence ont souligné comme une dépendance déjà :). merci – parliament

Répondre

8

La réponse est OUI, il a une méthode grep qui peut répondre à vos besoins. Par exemple:

inputs= jQuery.grep(inputs, function(input){ 
return input.length>0; 
}); 
if(inputs.length>0) return true; 
return false; 

Je ne le teste pas, peut-être qu'il a un problème mineur, mais devrait être presque comme ceci.

+0

De docs ressemble à ceci, mais je n'ai pas testé non plus. J'ai fini par aller avec Underscore.every() car j'avais déjà cela comme une dépendance de toute façon et ça correspond exactement au remplissage, renvoyant un booléen. – parliament

+6

Le problème avec ceci est que si le second de vos milliers d'éléments ne répond pas à l'exigence, il va encore vérifier tous les suivants au lieu de casser la boucle et retourner 'false'. Mais ça fonctionne. – bfontaine

3

Cela va passer par chaque élément, ET la condition avec le résultat précédent, de sorte qu'il ne retournera vrai que si la condition est vraie pour tous les éléments. Vous pouvez bien sûr remplacer la condition par une fonction de rappel, et faire inputs.each( au lieu de $('input') mais vous devrez peut-être ajuster le code un peu selon que les entrées sont un objet jquery ou non.

var all = true; 
    $('input').each(function(index, value) { 
    all = all & ($(value).val().length > 0); 
    }); 
return all; 
0

Pas exactement, mais il est facile de créer un:

$.eachCondition = function (obj, conditionFunction){ 
     var trueCount=0; 
     var falseCount=0; 

     $.each(obj, function (i,v) { 
      if (conditionFunction.call(this,i,v)) { 
      trueCount++; 
      } 
      else { 
      falseCount++; 
      } 
      }); 
      if (falseCount===0) { 
      return true; 
      } 
      if (trueCount===0) { 
      return false; 
      } 
      return undefined; 
     }; 
     $.fn.eachCondition = function (conditionFunction) { 
     return $.eachCondition(this, conditionFunction); 
     }; 

Voici essai fonctionne: http://jsbin.com/iwanof/2/

0

J'utilise habituellement formulaire ci-dessous pour obtenir les matchs dans JQuery

$.map($("[some selector]"), function(e) { 
    return ([some matching mechanism]); 
}).indexOf(false) == -1; 

Dans votre cas spécifique, cela ressemblerait à ceci:

$.map(inputs, function(e) { 
 
    return (e.length > 0); 
 
}).indexOf(false) == -1;

Espérons que cela vous permet d'économiser un certain temps.

+0

Je pense que vous pouvez également utiliser 'inputs.map (fonction ...'. –

2

Vous n'avez pas besoin d'utiliser jQuery pour cela. Vous pouvez le faire en JavaScript natif en utilisant Array.prototype.every, qui est pris en charge dans IE 9+.

function areAllValid(inputs){ 
    return inputs.every(function(input) { return input.length > 0; }); 
} 

Si vous utilisez EcmaScript 2015, vous pouvez ranger vers le haut plus:

var areAllValid = inputs => inputs.every(input => input.length > 0); 
+0

cela mérite d'être upvoted plus élevé –

0

Il y a quelques problèmes d'optimisation mineurs non adressés par les réponses existantes, donc je vais jeter mon chapeau dans l'anneau avec ce que je crois être le code le plus lisible/performant.

Ajouter une méthode d'extension jQuery comme celui-ci qui va court-circuit:

/** 
* Determines whether all elements of a sequence satisfy a condition. 
* @@param {function} predicate - A function to test each element for a condition. 
* @@return {boolean} true if every element of the source sequence passes the test in the specified predicate 
*/ 
$.fn.all = function (predicate) { 
    $(this).each(function (i, el) { 
     if (!predicate.call(this, i, el)) return false; 
    }); 
    // we made it this far, we're good. 
    return true; 
}; 

Ensuite, appelez comme ceci:

var allValid = $("form :input").all(function() { 
        return $(this).valid(); 
       }); 
0

rapide peu jQuery:

$(document).ready(function() { 
    $('form input').keyUp(function() { 
    var allValid = true; 
    $.each($('form input'), function(input) { 
     allValid = input.val().length > 0 
    } 
    if (allValid) 
     ... 
    else 
     ... 
    }) 
}); 
0
function areAllValid(inputs){ 
    return Array.prototype.every.call(inputs, function(input) { return input.length > 0; }); 
} 
Questions connexes