Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.
The previous article explained how to flatten the following objects, and this article will show how to reverse flatten (how to convert newobj to obj).
const obj = {
a: 'a'.b: [1.2, {c: [1.2.3.4]},4].c: { e: 5.f: 6 },
d: undefined.f: [1[1.2[5.6]]]};// Convert to the following new data structure:
const newobj = {
a: 'a'.'b[0]': 1.'b[1]': 2.'b[2].c[0]': 1.'b[2].c[1]': 2.'b[2].c[2]': 3.'b[2].c[3]': 4.'b[3]': 4.'c.e': 5.'c.f': 6.d: undefined.'f[0]': 1.'f[1][0]': 1.'f[1][1]': 2.'f[1][2][0]': 5.'f[1][2][1]': 6
}
Copy the code
1, Array to object
-
First, look at the object we want to convert. It is a single layer object. All we need to do is convert the key value to the object structure, such as c:{e:… }, solve this problem and the feature is 50% implemented.
-
So how do you convert C.E to an object structure? Let’s first implement how to convert an array to an object:
// Convert an array to a linked list structure (ps: a linked list is an object in JS)
const arr = ['a'.'b'.'c'.'d']
// Construct a conversion method
function transformToLink(arr){
// Construct a target object that we need
let head = {}
// Construct a pointer to iterate over the group switch
let tmp = head
for(let i =0; i<arr.length; i++) {let cur = arr[i]
// The current array deserves the next
let next = arr[i+1]
// When the next one exists, we construct a new object to assign, otherwise we simply assign undefined
if(next){
let o = {}
tmp[cur] = o
// We need to move the pointer to the next object
tmp = o
}else{
// If no, we'll just assign
tmp[cur] = undefined}}return head
}
Copy the code
- Test it out, no problem:
- This is where we implement array to object, so
c.e
No, you can go firstsplit
Split it into arrays and convert it?
2. We implemented the previous stepa.b.c.d.e.f
Convert to objects, but there are'b[2].c[0]'
,'f[1][2][0]'
This kind of structurekey
Next, we implement this part of the transformation.
- So let’s first look at the data structure when
key
Contained in the[]
When we construct an array object, we can not construct an object as above, but an array. Now, we can modify the above method:
// Convert key eg:key = b[2][0].c[0]
function transformkey(key){
const arr = key.split('. ')
let head = {}
let tmp = head
for(let i =0; i<arr.length; i++) {let key = arr[i]
let nextKey = arr[i + 1];
// If the key contains the string [], it is an array
if(/\[.+?\]/g.test(key)){
// Can be a multidimensional array, matching the array dimensions
let indexs = key.match(/\[(.+?)\]/g);
// Get the array key
let _key = key.match(/ ^ (. +?) \ [/) [1];
// Construct a new array
let n = []
tmp[_key] = n
// create an array
for(let j=0; j<indexs.length; j++){let index = indexs[j].replace(/\[|\]/g.' ');
let nextIndex = indexs[j+1]
// Array contains array
if(nextIndex){
let o = []
n[index] = o
// If it also contains an array, the n pointer points to the next array
n = o
}else{
// Construct the object if it follows
if (nextKey) {
let o = {}
n[index] = o
tmp = o
} else {
n[index] = undefined}}}}else {
// The array is not the same as the previous method
if (nextKey) {
let o = {}
tmp[key] = o
tmp = o
} else {
tmp[key] = undefined}}}return head
}
Copy the code
- Test it out:
- The data was successfully converted, since
key-value
(Note that conversion is to consider the construction of a new array or new object, need to determine whether the previous construction, after this part of the code will be expressed in the code) :
function unflatten(obj) {
let o = {}
for (let key in obj) {
transformKey(key, obj[key], o)
}
return o
}
//转化key
function transformKey(key,value,head){
const arr = key.split('. ')
let tmp = head
for(let i =0; i<arr.length; i++) {let key = arr[i]
let nextKey = arr[i + 1];
// If the key contains the string [], it is an array
if(/\[.+?\]/g.test(key)){
// Can be a multidimensional array, matching the array dimensions
let indexs = key.match(/\[(.+?)\]/g);
// Get the array key
let _key = key.match(/ ^ (. +?) \ [/) [1];
// To construct an array, check whether it already existstmp[_key] = tmp[_key]? tmp[_key]:[]let n = tmp[_key]
// create an array
for(let j=0; j<indexs.length; j++){let index = indexs[j].replace(/\[|\]/g.' ');
let nextIndex = indexs[j+1]
// Array contains array
if(nextIndex){
// To construct an array, check whether it already existsn[index] = n[index]? n[index]:[]// If it also contains an array, the n pointer points to the next array
n = n[index]
}else{
// Construct the object if it follows
if (nextKey) {
// To construct an object, you need to check whether it already existsn[index] = n[index]? n[index]:{} tmp = n[index] }else {
n[index] = value
}
}
}
} else {
// The array is not the same as the previous method
if (nextKey) {
// To construct an object, you need to check whether it already existstmp[key] = tmp[key]? tmp[key]:{} tmp = tmp[key] }else {
tmp[key] = value
}
}
}
return head
}
Copy the code
- Test results: