省市区树结构扁平化转换结构?

数据:
check:1 为选中


  [
    {
      "code": "110000",
      "value": "北京市",
      "checked":"1",
      "children": [
        {
          "code": "110100",
          "value": "北京市",
          "checked":"1",
          "children": [{
            "code": "110101",
            "value": "东城区",
            "checked":"1"
          }, {
            "code": "110102",
            "value": "西城区",
            "checked":"1"
          }]
        }
      ]
    },
    {
      "code": "120000",
      "value": "天津市",
      "checked":"1",
      "children": [{
        "code": "120100",
        "value": "天津市",
        "checked":"1",
        "children": [{
          "code": "120101",
          "value": "和平区",
          "checked":"0"
        }, {
          "code": "120102",
          "value": "河东区",
          "checked":"1"
        }]
      }]
    }
  ]

转化为:如果3级都选中了那就只获取1级和2级,如果2级都选中了,只获取1级,如3级选中某几个,获取1,2,3级

[
  {
    provinceAreald : '110000',
    cityAreald: null  //如2级全部选中为null
    countryAreald: null  //如3级全部选中为null
    actualAreaLevel:'1'
  },
  {
    provinceAreald : '120000',
    cityAreald: '120100'  //如2级全部选中为null
    countryAreald: '120102'  //如3级全部选中为null
    actualAreaLevel:'3' //层级
  }
]

求搭救

阅读 1.8k
2 个回答
function getNewData(data) {
  let d = []

  for (let province of data) {

    if (province.checked == 1) {
      let obj = {
        provinceAreald: province.code,
        cityAreald: null,
        countryAreald: null,
        actualAreaLevel: '1',
      }

      const cityArr = cityCheck(province, obj, d)

      if (cityArr.length == province.children.length) {
        Object.assign(obj, {
          cityAreald: null,
          actualAreaLevel: '1',
        })
        d.push(obj)  // 2级菜单被<全部>选中
      } else {
        d.push(...cityArr)  // 2级菜单被<部分>选中
      }

    }
  }


  function cityCheck(province, obj, d) {

    let cityArr = []
    for (let city of province.children) {

      if (city.checked == 1) {
        Object.assign(obj, {
          cityAreald: city.code,
          actualAreaLevel: '2',
        })

        // 参数obj, d可能被改变
        const countryArr = countryCheck(city, obj, d)

        if (countryArr.length == city.children.length) {
          Object.assign(obj, {
            countryAreald: null,
            actualAreaLevel: '2',
          })
          cityArr.push(obj)  // 3级菜单被<全部>选中
        } else {
          d = d.push(...countryArr)  // 3级菜单被<部分>选中
        }

      }

    }
    return cityArr

  }


  function countryCheck(city, obj, d) {

    let countryArr = []
    for (let country of city.children) {

      if (country.checked == 1) {
        countryArr.push(
          Object.assign(obj, {
            countryAreald: country.code,
            actualAreaLevel: '3',
          })
        )
      }

    }
    return countryArr
  }


  return d
}

const newData = getNewData(data)
console.log(newData)
  function findChecked (areas) {
      function createResItem (level, pCode = null, cCode = null, coCode = null) {
        return {
          provinceAreald: pCode,
          cityAreald: cCode,
          countryAreald: coCode, 
          actualAreaLevel: level
        }
      }
    
      function helper (nodes, level, codes) {
        if (!nodes || nodes.length === 0) return [true, []]
        
        let allChecked = true // 是否全选
        const res = [] // 收集返回值
        for (let i = 0; i < nodes.length; i++) {
          const node = nodes[i]
          codes.push(node.code)
          
          // childChecked:所有子节点是否全选;childRes:子节点返回值
          const [childChecked, childRes] = helper(node.children, level + 1, codes)
          // 如果子节点不全选或当前节点未选中,则设置当前全选为false,且收集子节点返回值;否则子节点全选则不收集子节点返回值,而是收集当前节点的返回值
          if (node.checked === '0' || !childChecked) allChecked = false
          if (node.checked === '0') continue 
          childChecked ? res.push(createResItem(String(level), ...codes)) : res.push(...childRes)
          
          codes.pop(node.code)          
        }
        
        return [allChecked, res]
      }
      
      return helper(areas, 1, [])[1]
    }
    console.log(findChecked(areas))
推荐问题
logo
Microsoft
子站问答
访问
宣传栏