Это пример реализации с аннотациями для объяснения того, что происходит на каждом шаге.
function maxValues(o, n) {
// Get object values and sort descending
const values = Object.values(o).sort((a, b) => b - a);
// Check if more values exist than number required
if (values.length <= n) return o;
// Find nth maximum value
const maxN = values[n - 1];
// Filter object to return only key/value pairs where value >= maxN
return Object.entries(o)
.reduce((o, [k, v]) => v >= maxN ? { ...o, [k]: v } : o, {});
}
const a = maxValues({
a: 5,
b: 10,
c: 15,
d: 20,
e: 20,
f: 25
}, 3);
console.log(a);
const b = maxValues({
a: 1,
b: 1,
c: 1,
d: 1,
e: 0.8,
f: 0.5
}, 3);
console.log(b);
const c = maxValues({
a: 5,
b: 10,
}, 3);
console.log(c);
Обратный вызов, переданный функции Array.prototype.reduce
, может быть расширен до следующего:
return Object.entries(o)
.reduce(function (obj, [key, value]) {
if (v >= maxN) {
return Object.assign(obj, {
[key]: value
});
} else {
return obj;
}
}, {});
Вместо этого я сжал его, используя Выражение функции стрелки , троичный оператор и расширенный синтаксис .
Тернарный оператор по существу является сокращением для оператора if/else
. Например,
condition ? true : false;
// or
v >= maxN ? { ...o, [k]: v } : o;
Синтаксис расширения позволяет развернуть итеративное значение на месте. В этом случае он используется для копирования существующих пар key/value
из одного литерала объекта в другой.
const a = { first_name: 'Rob', gender: 'male' };
const b = { ...a, username: 'fubar' };
console.log(b); // { first_name: 'Rob', gender: 'male', username: 'fubar' };