如何更优雅地处理多维数组foreach嵌套问题

比对获取到的省市区名称返回对应的value值,想用递归或者filter似乎都不太行得通,是否有又短又优雅的写法

getChinaArea(province,city,area){
                let result = []
                //直辖市
                if(!province){
                    this.localData.forEach((items)=>{
                        if(items.label === city){
                            result.push(items.value)
                            if(items.children){
                                items.children.forEach((item)=>{
                                    if(item.label === area){
                                        result.push(item.value)
                                    }
                                })
                            }
                        }
                    })
                }else{
                    //省市区
                    this.localData.forEach((items)=>{
                        if(items.label === province){
                            result.push(items.value)
                            if(items.children){
                                items.children.forEach((item)=>{
                                    if(item.label === city){
                                        result.push(item.value)
                                        if(item.children){
                                            item.children.forEach((i)=>{
                                                if(i.label === area){
                                                    result.push(i.value)
                                                }
                                            })
                                        }
                                    }
                                })
                            }
                        }
                    })
                }
                return result
            }

数据结构是这样的

{
        value: 3,
        label: '河北',
        children: [{
                value: 3,
                label: '石家庄市',
                children: [{
                        value: 37,
                        label: '长安区'
                    },
                    {
                        value: 38,
                        label: '桥东区'
                    },
                    {
                        value: 39,
                        label: '桥西区'
                    },
                    {
                        value: 40,
                        label: '新华区'
                    },
                    {
                        value: 41,
                        label: '井陉矿区'
                    },
                    {
                        value: 42,
                        label: '裕华区'
                    },
                    {
                        value: 43,
                        label: '井陉县'
                    },
                    {
                        value: 44,
                        label: '正定县'
                    },
                    {
                        value: 45,
                        label: '栾城县'
                    },
                    {
                        value: 46,
                        label: '行唐县'
                    },
                    {
                        value: 47,
                        label: '灵寿县'
                    },
                    {
                        value: 48,
                        label: '高邑县'
                    },
                    {
                        value: 49,
                        label: '深泽县'
                    },
                    {
                        value: 50,
                        label: '赞皇县'
                    },
                    {
                        value: 51,
                        label: '无极县'
                    },
                    {
                        value: 52,
                        label: '平山县'
                    },
                    {
                        value: 53,
                        label: '元氏县'
                    },
                    {
                        value: 54,
                        label: '赵县'
                    },
                    {
                        value: 55,
                        label: '辛集市'
                    },
                    {
                        value: 56,
                        label: '藁城市'
                    },
                    {
                        value: 57,
                        label: '晋州市'
                    },
                    {
                        value: 58,
                        label: '新乐市'
                    },
                    {
                        value: 59,
                        label: '鹿泉市'
                    }
                ]
            },
阅读 4.8k
8 个回答

借鉴Donle的代码,将res封装到函数中,拥有自己的函数作用域

  function findChild (data, list, res = []) {
    let info = list.shift()
    if (!info) return res
    let dataInfo = data.find(item => item.label === info)
    res.push(dataInfo.value)
    return dataInfo.children ? findChild(dataInfo.children, list, res) : res
  }
  console.log(findChild(localData, ['河北', '石家庄市', '桥东区']))
  console.log(findChild(localData, ['上海', '闵行区']))

建议把数据转成map类型的

用 map 啊。

创建一个树的对象啊。

function Node(data) {
    this.data = data;
    this.parent = null;
    this.children = [];
}
 
function Tree(data) {
    var node = new Node(data);
    this._root = node;
}

再创建5个方法
1.traverseDF(callback) 深度优先搜索
2.traverseBF(callback) 广度优先搜索
3.contains(data, traversal) 查询指定的值
4.add(child, parent) 添加节点
5.remove(node, parent) 删除节点

把原数据包装成数组,保证父子数据的一致性,然后递归:

const res = [];
const getChinaArea2 = (dataArray, ...labels) => {
    const layer = labels.shift();
    if (!layer) return;
    const result = dataArray.find(one => one.label === layer);
    if (result) {
        res.push(result.value);
        return result.children ? getChinaArea2(result.children, ...labels) : undefined;
    };
};
function getVal(f,d){
  for(var i=0,newArr = [];i<d.length;i++){
    if(d[i].label==f[0]){
      newArr.push(d[i]);
      f.shift();
      if(d[i]&&d[i].children&&f.length!=0){
        if(newArr.length==0)
          newArr[0].children.push(getVal(f,d[i].children));
        else
          newArr[0].children = getVal(f,d[i].children);
      }
    }
  }
  return newArr;
}
getVal(['河北'],data);
新手上路,请多包涵
function getChinaArea(province, city, area) {
  return [province, city, area]
    .filter(v => v)
    .reduce(
      (result, label) => {
        const item = result[0].filter(item => item.label === label)[0];
        item && result[1].push(item.value);
        return [(item && item.children) || [], result[1]];
      },
      [this.localData, []]
    )[1];
}

转成map类型

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题