Tout d'abord, il est considéré comme une mauvaise pratique d'étendre Object.prototype
. Au lieu de cela, fournissez votre fonctionnalité comme une fonction autonome, ou si vous voulez vraiment étendre un global, fournissez-la comme fonction utilitaire sur Object
comme il y en a déjà Object.keys
, Object.assign
, Object.is
, ...etc.
Je propose ici plusieurs solutions :
- Utilisation de
reduce
y Object.keys
- Comme (1), en combinaison avec
Object.assign
- Utilisation de
map
et la syntaxe de propagation au lieu de reduce
- Utilisation de
Object.entries
y Object.fromEntries
1. Utilisation de reduce
y Object.keys
Avec reduce
y Object.keys
pour mettre en œuvre le filtre souhaité (en utilisant ES6 syntaxe de la flèche ) :
Object.filter = (obj, predicate) =>
Object.keys(obj)
.filter( key => predicate(obj[key]) )
.reduce( (res, key) => (res[key] = obj[key], res), {} );
// Example use:
var scores = {
John: 2, Sarah: 3, Janet: 1
};
var filtered = Object.filter(scores, score => score > 1);
console.log(filtered);
Notez que dans le code ci-dessus predicate
doit être un inclusion (contrairement à la exclusion condition utilisée par le PO), de manière à ce qu'elle soit conforme à la façon dont les Array.prototype.filter
travaux.
2. Comme (1), en combinaison avec Object.assign
Dans la solution ci-dessus, le opérateur de virgule est utilisé dans le reduce
pour retourner la partie mutée res
objet. On pourrait bien sûr écrire 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 Object.assign
à la place, ce qui fait retourne l'objet muté :
Object.filter = (obj, predicate) =>
Object.keys(obj)
.filter( key => predicate(obj[key]) )
.reduce( (res, key) => Object.assign(res, { [key]: obj[key] }), {} );
// Example use:
var scores = {
John: 2, Sarah: 3, Janet: 1
};
var filtered = Object.filter(scores, score => score > 1);
console.log(filtered);
3. Utilisation de map
et la syntaxe de propagation au lieu de reduce
Ici, nous déplaçons le Object.assign
hors de la boucle, afin qu'il ne soit effectué qu'une seule fois, et transmettez-lui les clés individuelles en tant qu'arguments séparés (à l'aide de la balise syntaxe de l'étalement ) :
Object.filter = (obj, predicate) =>
Object.assign(...Object.keys(obj)
.filter( key => predicate(obj[key]) )
.map( key => ({ [key]: obj[key] }) ) );
// Example use:
var scores = {
John: 2, Sarah: 3, Janet: 1
};
var filtered = Object.filter(scores, score => score > 1);
console.log(filtered);
4. Utilisation de Object.entries
y Object.fromEntries
Comme la solution traduit l'objet en un tableau intermédiaire et le reconvertit ensuite en un objet ordinaire, il serait utile d'utiliser la fonction Object.entries
(ES2017) et l'inverse (c'est-à-dire créer un objet à partir d'un tableau de paires clé/valeur ) avec Object.fromEntries
(ES2019).
Cela mène à cette méthode "one-liner" sur Object
:
Object.filter = (obj, predicate) =>
Object.fromEntries(Object.entries(obj).filter(predicate));
// Example use:
var scores = {
John: 2, Sarah: 3, Janet: 1
};
var filtered = Object.filter(scores, ([name, score]) => score > 1);
console.log(filtered);
La fonction prédicat reçoit 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 prédicat.