В этом скрипте я ищу свойства в массиве объектов. Есть исходный массив строк list чтобы получить объекты, соответствующие name собственности, затем я ищу их соответствующих линейных руководителей, reports рекурсивно, но только до rank 2, наконец, объединяю их записи с менеджерами.
Мне было интересно, есть ли более эффективный способ достичь этого результата, поскольку мне нужно создать объект для индексации менеджеров, которые уже были проверены, иначе я получаю дубликаты, когда у двух людей один и тот же менеджер. Также необходимо указать rank ограничить дважды.
const data = [
{
name: 'rebecca',
reports: '',
rank: 1
},
{
name: 'will',
reports: 'rebecca',
rank: 2
},
{
name: 'jose',
reports: 'will',
rank: 3
},
{
name: 'tomas',
reports: 'jose',
rank: 4,
},
{
name: 'matt',
reports: 'jose',
rank: 5
},{
name: 'alison',
reports: 'john',
rank: 5
}
]
// Initial list of names
const list = ['tomas', 'matt']
// Get the people on the list first
const filterList = data.filter(({ name }) => list.includes(name))
// Helper object to account for managers already checked and avoid duplicates
const managers = {}
// Find missing managers recursively
const findManager = (manager) => {
const next = data.find(({ name }) => name === manager)
managers[next.name] = true
return next.rank > 2 ? [next, ...findManager(next.reports)] : [next]
}
// Get the line managers for the filterList array
const missingManagers = []
for (const { reports, rank } of filterList) {
if (!list.includes(reports) && rank > 2 && !managers[reports] ) {
missingManagers.push(...findManager(reports))
}
}
const result = [...missingManagers, ...filterList]
console.log(result).as-console-wrapper { max-height: 100% !important; top: 0; } 1 ответ
Из среднего обзора;
- Этот код принадлежит хорошо названной функции
- Я всегда забываю о деструктуризации в
filter, очень хорошо - Сопоставление с объектом автоматически удаляет дубли, что я (ab) использую в своем счетчике
const findManager = (manager)вероятно должно бытьconst findManager = (employee)const findManager = (employee)вероятно должно бытьconst findLineManagers = (employee)- Оттуда,
nextвероятно должно бытьmanager, это определенно не «следующий», а более «актуальный»;) - Вы не используете точку с запятой, если не понимаете все нюансы, вы должны использовать их
- В рекурсивном программировании более идиоматично сначала проверять условие выхода, чем потом проверять в конце, нужно ли вам рекурсивно или нет
Я боролся с этим встречным предложением. Я полагаю, что в поддерживаемой мной кодовой базе я хотел бы, чтобы моя структура данных была связана. Таким образом, эта функция получает связанную версию данных, а затем получает то, что необходимо, более простым способом. YMMV.
// Initial list of names
function indexPeopleData(peopleData){
//Index by name
const indexedPeople = peopleData.reduce((out,person) => (out[person.name] = person, out), {});
//Make reports point to a people object
peopleData.forEach(person => person.reports = indexedPeople[person.reports]);
return indexedPeople;
}
function getLineManagers(peopleData, names){
const indexedPeople = indexPeopleData(peopleData);
//Return list of employees and their managers
let out = {}, name;
while(name = names.pop()){
out[name] = indexedPeople[name];
if(out[name].reports.rank > 1){
names.push(out[name].reports.name);
}
}
return Object.values(out);
}
var data = [
{
name: 'rebecca',
reports: '',
rank: 1
},
{
name: 'will',
reports: 'rebecca',
rank: 2
},
{
name: 'jose',
reports: 'will',
rank: 3
},
{
name: 'tomas',
reports: 'jose',
rank: 4,
},
{
name: 'matt',
reports: 'jose',
rank: 5
},{
name: 'alison',
reports: 'john',
rank: 5
}
];
console.log(getLineManagers(data, ['tomas', 'matt']));
Спасибо за ваш ответ, это интересный подход, однако вывод неверен, это должна быть плоская коллекция объектов в массиве без более глубоких уровней.
— Альваро