ECMAScript 5 a le filter()
prototype pour les Array
types, mais pas pour les Object
types, si je comprends bien.
Comment implémenter un filter()
for Object
s en JavaScript?
Disons que j'ai cet objet:
var foo = {
bar: "Yes"
};
Et je veux écrire un filter()
qui fonctionne sur Object
s:
Object.prototype.filter = function(predicate) {
var result = {};
for (key in this) {
if (this.hasOwnProperty(key) && !predicate(this[key])) {
result[key] = this[key];
}
}
return result;
};
Cela fonctionne lorsque je l'utilise dans la démo suivante, mais lorsque je l'ajoute à mon site qui utilise jQuery 1.5 et jQuery UI 1.8.9, j'obtiens des erreurs JavaScript dans FireBug.
javascript
jquery
object
filtering
AgileMeansDoAsLittleAsPossible
la source
la source
Object.prototype
: bugs.jquery.com/ticket/2721Réponses:
Jamais jamais prolonger
Object.prototype
.Des choses horribles vont arriver à votre code. Les choses vont casser. Vous étendez tous les types d'objets, y compris les littéraux d'objet.
Voici un exemple rapide que vous pouvez essayer:
Au lieu de cela, créez une fonction que vous passez l'objet.
la source
Object.prototype
, mais plutôt de simplement activer la fonctionObject
. Deuxièmement, c'est le code de l'OP . Il est clair que l'intention d'OP est d'.filter()
être telle qu'elle filtre les résultats positifs. En d'autres termes, il s'agit d'un filtre négatif, où une valeur de retour positive signifie qu'il est exclu du résultat. Si vous regardez l'exemple jsFiddle, il filtre les propriétés existantes qui le sontundefined
.Object.prototype
. De la question: "Cela fonctionne ..., mais quand je l'ajoute à mon site ..., j'obtiens des erreurs JavaScript" Si OP décide d'implémenter un.filter()
avec le comportement opposé de celui deArray.prototpe.filter
, c'est à lui / elle. Veuillez laisser un commentaire sous la question si vous souhaitez informer OP que le code est erroné, mais ne me dites pas que je le fais mal alors que ce n'est pas mon code.Tout d'abord, il est considéré comme une mauvaise pratique de s'étendre
Object.prototype
. Au lieu de cela, indiquez votre fonction en fonction d'utilité surObject
, comme il y a déjàObject.keys
,Object.assign
,Object.is
, ... etc.Je propose ici plusieurs solutions:
reduce
etObject.keys
Object.assign
map
et diffuser la syntaxe au lieu dereduce
Object.entries
etObject.fromEntries
1. Utilisation
reduce
etObject.keys
Avec
reduce
etObject.keys
pour implémenter le filtre souhaité (en utilisant la syntaxe des flèches ES6 ):Notez que dans le code ci-dessus
predicate
doit être une condition d' inclusion (contrairement à la condition d' exclusion utilisée par l'OP), afin qu'elle corresponde à la façon dontArray.prototype.filter
fonctionne.2. Comme (1), en combinaison avec
Object.assign
Dans la solution ci-dessus, l' opérateur virgule est utilisé dans la
reduce
partie pour renvoyer l'res
objet muté . Cela pourrait bien sûr être écrit comme deux déclarations au lieu d'une seule expression, mais cette dernière est plus concise. Pour le faire sans l'opérateur virgule, vous pouvez utiliser à laObject.assign
place, qui ne retourne l'objet muté:3. Utiliser
map
et diffuser la syntaxe au lieu dereduce
Ici, nous déplaçons l'
Object.assign
appel hors de la boucle, donc il n'est fait qu'une seule fois, et lui passons les clés individuelles comme arguments séparés (en utilisant la syntaxe de propagation ):4. Utilisation
Object.entries
etObject.fromEntries
Comme la solution traduit l'objet en un tableau intermédiaire, puis le convertit en un objet simple, il serait utile d'utiliser
Object.entries
(ES2017) et l'opposé (c'est-à-dire créer un objet à partir d'un tableau de paires clé / valeur ) avecObject.fromEntries
( ES2019).Cela conduit à cette méthode "one-liner" sur
Object
:La fonction de prédicat obtient ici une paire clé / valeur comme argument, ce qui est un peu différent, mais permet plus de possibilités dans la logique de la fonction de prédicat.
la source
x => x.Expression.Filters.Filter
.Filter
y a à la fin, mais si c'est une fonction, il faut l'appeler (x => x.Expression.Filters.Filter()
)Si vous êtes prêt à utiliser un trait de soulignement ou un lodash , vous pouvez utiliser
pick
(ou son contraireomit
).Exemples tirés de la documentation du trait de soulignement:
Ou avec un rappel (pour lodash , utilisez pickBy ):
la source
Approche ES6 ...
Imaginez que vous avez cet objet ci-dessous:
Créez une fonction:
Et appelez-le:
et va reviendra :
la source
!predicate
dans leur propre code).Comme Patrick l'a déjà dit, c'est une mauvaise idée, car cela cassera presque certainement tout code tiers que vous pourriez souhaiter utiliser.
Toutes les bibliothèques comme jquery ou prototype se casseront si vous étendez
Object.prototype
, la raison étant que l'itération paresseuse sur les objets (sanshasOwnProperty
vérifications) se cassera puisque les fonctions que vous ajoutez feront partie de l'itération.la source
Que diriez-vous:
Ou...
la source
Donné
puis :
Afficher l'extrait de code
la source
J'ai créé un
Object.filter()
qui ne filtre pas seulement par une fonction, mais accepte également un tableau de clés à inclure. Le troisième paramètre optionnel vous permettra d'inverser le filtre.Donné:
Tableau:
Fonction:
Code
Avertissement : j'ai choisi d'utiliser le noyau Ext JS par souci de concision. Je n'ai pas jugé nécessaire d'écrire des vérificateurs de type pour les types d'objet car cela ne faisait pas partie de la question.
la source
Ma solution opiniâtre:
Cas de test:
https://gist.github.com/bernardoadc/872d5a174108823159d845cc5baba337
la source
Solution en Vanilla JS à partir de l'année 2020.
Vous pouvez filtrer l'
romNumbers
objet par clé:Ou filtrer l'
romNumbers
objet par valeur:la source
Si vous souhaitez muter le même objet plutôt que d'en créer un nouveau.
L'exemple suivant supprimera toutes les valeurs 0 ou vides:
la source
Comme tout le monde l'a dit, ne bousillez pas avec le prototype. Au lieu de cela, écrivez simplement une fonction pour le faire. Voici ma version avec
lodash
:la source
J'utilise ceci quand j'en ai besoin:
la source
Dans ces cas, j'utilise le jquery $ .map, qui peut gérer des objets. Comme mentionné sur d'autres réponses, ce n'est pas une bonne pratique de changer les prototypes natifs ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain#Bad_practice_Extension_of_native_prototypes )
Vous trouverez ci-dessous un exemple de filtrage en vérifiant simplement une propriété de votre objet. Il retourne le propre objet si votre condition est vraie ou retourne
undefined
sinon. Laundefined
propriété fera disparaître cet enregistrement de votre liste d'objets;la source
$.map
peut prendre un objet, mais il renvoie un tableau, de sorte que les noms de propriété d'origine sont perdus. L'OP a besoin d'un objet brut filtré.