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, soc.eNo, you can go firstsplitSplit it into arrays and convert it?

2. We implemented the previous stepa.b.c.d.e.fConvert to objects, but there are'b[2].c[0]','f[1][2][0]'This kind of structurekeyNext, we implement this part of the transformation.

  • So let’s first look at the data structure whenkeyContained 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, sincekey-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: