Przede wszystkim przedłużanie uważa się za złą praktykęObject.prototype
. Zamiast podać funkcję jako funkcji użyteczności na Object
, jak już tam są Object.keys
, Object.assign
, Object.is
, ... etc.
Podaję tutaj kilka rozwiązań:
- Korzystanie
reduce
iObject.keys
- Jak (1), w połączeniu z
Object.assign
- Używanie
map
i rozkładanie składni zamiastreduce
- Korzystanie
Object.entries
iObject.fromEntries
1. Używanie reduce
iObject.keys
Za pomocą reduce
i Object.keys
aby zaimplementować żądany filtr (używając składni strzałek ES6 ):
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);
Zauważ, że w powyższym kodzie predicate
musi być warunek włączenia (w przeciwieństwie do warunku wyłączenia zastosowany OP), aby był zgodny z tym, jak Array.prototype.filter
działa.
2. Jak (1) w połączeniu z Object.assign
W powyższym rozwiązaniu operator przecinka jest używany w reduce
części, aby zwrócić zmutowany res
obiekt. Można to oczywiście zapisać jako dwie wypowiedzi zamiast jednego wyrażenia, ale to drugie jest bardziej zwięzłe. Aby to zrobić bez operatora przecinek, można użyć Object.assign
zamiast tego, który ma powrócić zmutowaną obiektu:
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. Używanie map
i rozkładanie składni zamiastreduce
Tutaj przenosimy Object.assign
wywołanie z pętli, więc jest ono wykonywane tylko raz i przekazujemy poszczególne klucze jako osobne argumenty (przy użyciu składni rozszerzonej ):
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. Używanie Object.entries
iObject.fromEntries
Ponieważ rozwiązanie przekształca obiekt w tablicę pośrednią, a następnie przekształca go z powrotem w zwykły obiekt, przydatne byłoby skorzystanie z Object.entries
(ES2017) i odwrotnie (tj. Utworzenie obiektu z tablicy par klucz / wartość ) za pomocą Object.fromEntries
( ES2019).
Prowadzi to do tej metody „one-liner” na 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);
Funkcja predykatu otrzymuje tutaj argument klucz / wartość, co jest nieco inne, ale pozwala na więcej możliwości w logice funkcji predykatu.