2017-01-31 5 views
1

Я хотел бы взять объектный литерал и преобразовать его в новый объект, где новые ключи объектов - это пути.Преобразовать объект в литерал к объекту, содержащему пути?

const obj = { 
    test: { 
    qwerty: 'text', 
    abc: { 
     testing: 123 
    } 
    } 
} 

To:

{ 
    'test.qwerty': 'text', 
    'test.abc.testing': 123 
} 

Я смотрел через lodash docs, но я не вижу ничего, что могло бы сделать это быстро.

Объектом буквальным может быть любое количество уровней в глубину.

Каков наилучший способ приблизиться к этому ..?

ответ

1

Не знаю, если lodash имеет какой-либо встроенной функции, но это подход с использованием ES6 arrow functions, необязательные параметры и рекурсивный вызов:

const obj = { 
    test: { 
    qwerty: 'text', 
    abc: { 
     testing: 123 
    } 
    } 
} 


pathMyObject = (obj, prefix, newObj = {}) => { 
    Object.keys(obj).forEach(key => { 
     const value = obj[key]; 
     const newPrefix = (!prefix ? key : prefix + "." + key) 
     if (typeof value === 'object') { 
      pathMyObject(value, newPrefix, newObj) 
     } else { 
      newObj[newPrefix] = value; 
     } 
    }) 
    return newObj 
} 

const path = pathMyObject(obj); 

console.log(path); 
/* 
    { 
    'test.qwerty': 'text', 
    'test.abc.testing': 123 
    } 
*/ 
0

Вы можете создать рекурсивную функцию для создания объекта, подобного этому.

const obj = { 
 
    test: { 
 
    qwerty: 'text', 
 
    abc: { 
 
     testing: 123 
 
    } 
 
    } 
 
} 
 

 
function toStrings(data) { 
 
    var r = {} 
 

 
    function inner(data, c) { 
 
    for (var i in data) { 
 
     if (typeof data[i] == 'object') inner(data[i], c + i + '.') 
 
     else r[(c + i).replace(/\.$/, "")] = data[i] 
 
    } 
 
    } 
 
    inner(data, ''); 
 
    return r; 
 
} 
 

 
console.log(toStrings(obj))

+0

Вот более сложный пример https://jsfiddle.net/ Lg0wyt9u/1488 / –

1

Вот рекурсивный используя функцию Lodash's reduce.

const obj = { 
 
    test: { 
 
    qwerty: 'text', 
 
    abc: { 
 
     testing: 123 
 
    } 
 
    } 
 
}; 
 

 
function toPaths(obj, path) { 
 
    if (typeof obj !== 'object') { return { [path]: obj }; } 
 
    return _.reduce(obj, (result, value, key) => 
 
    Object.assign({}, result, toPaths(value, path ? `${path}.${key}` : key)) 
 
    , {}); 
 
} 
 

 
console.log(toPaths(obj));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

Это лишь немного компактнее, чем не-Lodash эквивалент:

const obj = { 
 
    test: { 
 
    qwerty: 'text', 
 
    abc: { 
 
     testing: 123 
 
    } 
 
    } 
 
}; 
 

 
function toPaths(obj, path) { 
 
    if (typeof obj !== 'object') { return { [path]: obj }; } 
 
    return Object.keys(obj).reduce((result, key) => 
 
    Object.assign({}, result, toPaths(obj[key], path ? `${path}.${key}` : key)) 
 
    , {}); 
 
} 
 

 
console.log(toPaths(obj));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>