Я пытаюсь уменьшить массив объектов (значения конфигурации в моем случае).Мой массив выглядит так:
const settings = [
{room: null, key: 'radioEnabled', value: true},
{room: 24, key: 'radioEnabled', value: false},
{room: 24, key: 'name', value: 'Jack'},
{room: 23, key: 'name', value: 'Mike'},
{room: 23, key: 'radioEnabled', value: false},
{room: null, key: 'tvEnabled', value: false},
];
Этот массив никак не упорядочен.
Если для комнаты установлено значение null
, это означает, что это глобальная настройка.Глобальные настройки могут быть перезаписаны локальными настройками.
Я пытаюсь написать функцию, чтобы получить все настройки для комнаты.Для комнаты 24 он должен вернуть:
[
{room: 24, key: 'radioEnabled', value: false},
{room: 24, key: 'name', value: 'Jack'},
{room: null, key: 'tvEnabled', value: false},
]
Порядок, в котором возвращаются значения, для меня не важен.Мне удалось достичь этого несколькими способами, но решения просто не кажутся мне такими элегантными / читаемыми.Кто-нибудь может предложить более элегантную идею?
Мои решения приведены ниже и на jsfiddle .
const settings = [
{room: null, key: 'radioEnabled', value: true},
{room: 24, key: 'radioEnabled', value: false},
{room: 24, key: 'name', value: 'Jack'},
{room: 23, key: 'name', value: 'Mike'},
{room: 23, key: 'radioEnabled', value: false},
{room: null, key: 'tvEnabled', value: false},
];
const getAll_1 = function(room){
return settings.reduce( (a, b) => {
// remove all other rooms
if(b.room && b.room!== room){
return a;
}
// see if the setting is already added
let found = a.find( (setting) => {
return setting.key === b.key;
})
// we already have a local value in our return array, don't add/replace anything
if( found && found.room === room) {
return a;
}
// we have a value, but it's not local. Replace the current value with the new one
if( found ) {
const index = a.findIndex( (setting) => {
return setting.key === b.key;
})
a[index] = b;
return a;
}
// we don't have this setting at all. add it.
return a.concat(b);
}, []);
}
const getAll_2 = function(room){
return settings
// first filter out all other room settings, only keep current room and global values
.filter( (setting) => {
return setting.room === null || setting.room === room;
})
// than sort em so all local (high prio) values are up top
.sort( (a, b) => {
return (a.room > b.room) ? -1 : ( a.room < b.room ) ? 1 : 0;
})
// reduce the array, adding only global values if they are not already added as local value
.reduce( (a, b) => {
const found = a.find( (setting) => {
return setting.key === b.key;
})
if (found){
return a;
}
return a.concat(b);
}, [])
}
console.log(`Stack Overflow does not support console.table. Open your console for better representation`);
console.log(`getAll_1 response:`);
console.table(getAll_1(24));
console.log(`getAll_2 response:`);
console.table(getAll_2(24));
Check your console