对json数据的操作

一维数组转成树形结构

源数据:

export const regions = [
  {
    'code': '51',
    'name': '四川省',
    'pid': '0' // 区域的父级区域 id
  },
  {
    'code': '5101',
    'name': '成都市',
    'pid': '51' // 成都的父级是四川省,所以 pid 是 51
  },
  {
    'code': '510104',
    'name': '锦江区',
    'pid': '5101'
  },
  {
    'code': '50',
    'name': '重庆市',
    'pid': '0'
  },
  {
    'code': '5001',
    'name': '市辖区',
    'pid': '50'
  },
  {
    'code': '500101',
    'name': '万州区',
    'pid': '5001'
  }
  // ...
]

转换成树结构:

[
    {
        "code": "51", 
        "name": "四川省", 
        "pid": "0", 
        "children": [
            {
                "code": "5101", 
                "name": "成都市", 
                "pid": "51", 
                "children": [
                    {
                        "code": "510104", 
                        "name": "锦江区", 
                        "pid": "5101", 
                        "children": [ ]
                    }
                ]
            }
        ]
    }, 
    {
        "code": "50", 
        "name": "重庆市", 
        "pid": "0", 
        "children": [
            {
                "code": "5001", 
                "name": "市辖区", 
                "pid": "50", 
                "children": [
                    {
                        "code": "500101", 
                        "name": "万州区", 
                        "pid": "5001", 
                        "children": [ ]
                    }
                ]
            }
        ]
    }
]

toTree函数接收的参数regions代表一维数据数组,rootId代表树形结构中根节点的pid。toTree函数返回的是指定根节点(pid=rootId的)的树结构,所以我们只需逐渐降低rootId,递归调用toTree函数不断获取下一层的树形结构即可。
常规方法:

function toTree(regions, rootId) {
  // TODO: 在这里写入具体的实现逻辑
  // 将平铺的结构转化为树状结构,并将 rootId 下的所有子节点数组返回
  // 如果不存在 rootId 下的子节点,则返回一个空数组
  const arr = []
  for (let i = 0; i < regions.length; i++) {
    if (regions[i]['pid'] === rootId) {
      regions[i].children = toTree(regions, regions[i]['code'])
      arr.push(regions[i])
    }
  }
  return arr
}
console.log(JSON.stringify(toTree(region, '0')))

toTree函数执行一次就找到了一层数据,每一个数据被找到时就开始以该数据为根节点去递归调用toTree函数找下一层的数据。每一次调用toTree函数就会遍历一遍regions数组,如果最终的树形结构有三层,那么就需要遍历三遍regions数组。

高级方法:

function toTree(regions, rootId) {
  // TODO: 在这里写入具体的实现逻辑
  // 将平铺的结构转化为树状结构,并将 rootId 下的所有子节点数组返回
  // 如果不存在 rootId 下的子节点,则返回一个空数组
  return regions.reduce((result, current) => {
    if (current['pid'] === rootId) {
      current.children = toTree(regions, current['code'])
      result.push(current)
    }
    return result
  }, [])
}
console.log(JSON.stringify(toTree(region, '0')))

reduce的第二个参数是一个空数组,所以:
第一次执行时,result=[],current=regions[0]。然后进行判断,如果current是根节点的话就以current的id作为下一层根节点pid递归调用toTree得到下一层的数据赋值给current.children,之后将current添加进result中,随后return出result。
第二次执行时,result为第一次执行返回的数组,current=regions[1]
第三次执行时,result为第二次执行返回的数组,current=regions[2]

通过子节点,查找上级所有父节点

使用上面我们转换成树形结构数据,通过区域code找到所有的父节点
展示结果:
输入"锦江区"时,返回 [ “四川省”, “成都市”, 锦江区 ]。
输入"成都市", 则返回 [ “四川省”, “成都市” ]。
输入"四川省", 则返回 [ “四川省” ]。

方法一

function findParents(regionName, regions) {
  const arr = []
  const findFn = (name, tree) => {
    for (const item of tree) {
      if (item.name === name) {
        arr.unshift(item)
        return true
      } else if (item.children && Array.isArray(item.children) && item.children.length) {
        const result = findFn(name, item.children)
        if (result) {
          arr.unshift(item)
          return true
        }
      }
    }
    return false
  }
  findFn(regionName, regions)
  return arr.map(item => item.name)
}
console.log(findParents('锦江区', regionsTree))//[ “四川省”, “成都市”, 锦江区 ]

方法二

const getParents = (regionName, tree) => {
  for (const index in tree) {
    if (tree[index]['name'] === regionName) {
      return [tree[index]]
    }
    if (tree[index].children) {
      const node = getParents(regionName, tree[index].children)
      if (node !== undefined) {
        const rsNode = node.concat(tree[index])
        return rsNode
      }
    }
  }
}
console.log(console.log(getParents('锦江区', regionsTree).reverse().map(item => item.name)))//[ “四川省”, “成都市”, 锦江区 ]

方法三

const reduceParents = (regionName, tree) => {
  return tree.reduce((pre, current) => {
    if (current['name'] === regionName) {
      pre.push(current)
    }
    if (current.children) {
      const node = reduceParents(regionName, current.children)
      if (node.length > 0) {
        const pre = node.concat(current)
        return pre
      }
    }
    return pre
  }, [])
}
console.log(console.log(reduceParents('锦江区', regionsTree).reverse().map(item => item.name)))//[ “四川省”, “成都市”, 锦江区 ]

 上一篇
shell脚本编写简单入门 shell脚本编写简单入门
helloworld入门 使用编辑器vim 创建并添加语句 vim helloworld.sh #! /bin/bash echo 'helloworld' #! /bin/bash 是指此脚本使用/bin/bash来解释执行。 echo
2022-11-06
下一篇 
简单使用FFmpeg 简单使用FFmpeg
视频转换 ffmpeg -i input.mp4 -acodec copy -vcodec h264 -s 720x1280 output.ts h264 表示输出的是h264的视频裸流 -i 设定输入流 -s 设定画面的宽与高 -vco
2022-10-19
  目录