Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

树形数据结构扁平化 #23

Open
metroluffy opened this issue May 21, 2020 · 2 comments
Open

树形数据结构扁平化 #23

metroluffy opened this issue May 21, 2020 · 2 comments
Assignees

Comments

@metroluffy
Copy link
Owner

编写两个函数,实现如下两个数据结构互相转换

const data = {
  a: {
    b: {
      c: {
        dd: 'abcdd'
      }
    },
    d: {
      xx: 'adxx'
    },
    e: 'ae'
  }
}
const output = {
  'a.b.c.dd': 'abcdd',
  'a.d.xx': 'adxx',
  'a.e': 'ae'
}
@metroluffy metroluffy self-assigned this May 21, 2020
@metroluffy
Copy link
Owner Author

// 辅助函数
const isObj = obj => Object.prototype.toString.call(obj) === '[object Object]'

// 扁平化树形结构
function flattenNTreeHelper (data, ans, prevKey = '') {
  Object.keys(data).forEach(key => {
    const currKey = prevKey ? prevKey + '.' + key : key
    const currVal = data[key]
    if (isObj(currVal)) {
      flattenNTreeHelper(currVal, ans, currKey)
    } else {
      ans[currKey] = currVal
    }
  })
}
function flattenNTree (data) {
  if (!isObj(data)) return data
  const ans = {}
  flattenNTreeHelper(data, ans, '')
  return ans
}
// 扁平化结构转树形
function nTreeConstruct (data) {
  if (!isObj(data)) return data
  const ans = {}
  Object.keys(data).forEach(key => {
    // 按 . 分割key, 顺带支持一下形如 'z[0]'的格式
    const keys = key.replace(/\[(\d+)\]/g, '.$1').split('.')
    let curr = ans
    for (let i = 0; i < keys.length - 1; i++) {
      curr[keys[i]] = curr[keys[i]] || {}
      curr = curr[keys[i]]
    }
    curr[keys[keys.length - 1]] = data[key]
  })
  return ans
}

@metroluffy
Copy link
Owner Author

再考虑以下数据:

const data = {
  a: {
    b: {
      c: {
        dd: 'abcdd'
      }
    },
    e: 'ae',
    g: [1, { g1: 6 }, [1, 2]]
  }
}
// 期望输出
const output = {
   'a.b.c.dd': 'abcdd',
   'a.e': 'ae',
   'g[0]': 1,
   'g[1].g1': 6,
   'g[2][0]': 1,
   'g[2][1]': 2
}

也就是生成key的时候要多考虑一个数组类型,实现如下:

function flattenNTreeHelper (data, ans, prevKey = '', isArr = false) {
  Object.keys(data).forEach(key => {
    const currKey = prevKey ? (prevKey + (isArr ? ('[' + key + ']') : ('.' + key))) : key
    const currVal = data[key]
    const dataIsArr = Array.isArray(currVal)
    if (isObj(currVal) || dataIsArr) {
      flattenNTreeHelper(currVal, ans, currKey, dataIsArr)
    } else {
      ans[currKey] = currVal
    }
  })
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant