нахождения всех ключей в объекте
Добрых времени суток, есть такая задача: необходимо написать функцию для обработки ключей объекта. Функция должна принимать два аргумента:
Объект/Массив, ключи которого необходимо конвертировать;
Формат, в который необходимо преобразовать ключи (uppercase, lowercase);
На данный момент на 2-ой пункт можно не обращать внимания (но кому очень интересно - буду рад решению), вот что имею:
const obj = [{
"key1": 1,
"key2": "hello_world",
"key3": {
"key4": {
"key5": [{
"key6": "hello_world",
"key7": {
"key8": 2
}
}]
}
}
}];
const keys = [];
const fn = obj => {
Object.keys({...obj}).forEach(key => {
if (typeof obj[key] == 'object') {
keys.push(key);
fn(obj[key]);
} else {
keys.push(key);
}
});
return keys;
}
console.log(fn(obj))
Вопросы:
- Как избежать
'0'в выходном объекте? - Каким образом можно перенести
keysв саму функцию? (пытался через замыкание, но не вышло);
Если кто возьмётся помочь, то, если не затруднит, как можно подробнее объяснить поведение.
Ответы (2 шт):
Число 0 возникает из-за того, что массивы в JS - на самом деле объекты с числовыми ключами:
console.log( Object.keys( ["My", "test", "array"] ) );
Перед push надо проверять, не являлся ли объект массивом. Для этого существует или Array.isArray(obj) или obj instanceof Array → https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
const obj = [{
"tEsTcAmEl1": 1,
"key2": "hello_world",
"key3": {
"key4": {
"key5": [{
"key6": "hello_world",
"key7": {
"key8": 2
}
}]
}
}
}];
console.log( deepObjectKeys(obj, 'upper') );
/*****/
function deepObjectKeys(obj, letterCase) {
let cases = {
"upper": key => key.toUpperCase(),
"lower": key => key.toLowerCase(),
};
let setCase = cases[letterCase] || ( key => key );
// throw new Error('???');
let keyStorage = [];
storeKeysRecursive(obj);
return keyStorage;
/***/
function storeKeysRecursive(obj) {
if (obj instanceof Object) {
let notArrayKey = !Array.isArray(obj);
Object.keys({...obj}).forEach(key => {
if (notArrayKey) keyStorage.push( setCase(key) );
return storeKeysRecursive( obj[key] );
})
}
}
}
const obj = [{
"key1": 1,
"key2": "hello_world",
"key3": {
"key4": {
"key5": [{
"key6": "hello_world",
"key7": {
"key8": 2
}
}]
}
}
}];
const fn = obj => {
const keys = [];
Object.keys({...obj}).forEach(key => {
if (typeof obj[key] == 'object') {
if(!Array.isArray(obj)) keys.push(key); //(1)
keys.push(...fn(obj[key])); //(2)
} else {
keys.push(key);
}
});
return keys;
}
console.log(fn(obj))
Не знаю смог ли я объяснить?
- 0 появляется потому-что это ключ массива(0, 1, 2, ...), поэтому я просто сделал проверку, если это не массив то пушить ключ;
- Чтобы keys была в функции, причем через рекурсию, надо чтобы рекурсивная функция вернула результат работы, и все понятно, она вернёт массив, нужно его раскрыть, а потом естественно добавить в массив там где была вызвана рекурсия.
Звучит сложно только в тексте, но если представить в голове все станет ясно.