来个 js 算法大牛看看这个题,有没有优雅点的代码?

源数据

const data = [
  {
    city:'浙江',
    children:[
      {
        city:'宁波',
        children:[{
          city:'鄞州区',
          children:[]
        },{
          city:'江北区',
          children:[]
        }]
      },
      {
        city:'杭州',
        children:[{
          city:'富阳',
          children:[]
        },{
          city:'上城区',
          children:[]
        }]
      }
    ]
  },
  {
    city:'上海',
    children:[
      {
        city:'黄浦区',
        children:[]
      }
    ]
  }
]

目标结构

[
  "浙江,宁波,鄞州区",
  "浙江,宁波,江北区",
  "浙江,杭州,富阳",
  "浙江,杭州,上城区",
  "上海,黄浦区"
]
阅读 7.2k
9 个回答

solution 1

function flatTree(nodes, parents = []) {
    const pathes = nodes
        .filter(({ children }) => !children?.length)
        .map(({ city }) => [...parents, city]);
    const subPathes = nodes.filter(({ children }) => children?.length)
        .flatMap(({ city, children }) => flatTree(children, [...parents, city]));
    return pathes.concat(subPathes);
}

solution 2

function flatTree(nodes, parents = []) {
    return nodes.flatMap(({ city, children }) => {
        return children?.length
            ? flatTree(children, [...parents, city])
            : [[...parents, city]];
    });
}

using

console.log(flatTree(data).map(path => path.join(",")));
//                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
const getAreasInProvince=(province)=>{
    const result=[]
    const t=(node,temp=node.city)=>{
        if(!node.children.length){
            result.push(temp)
        }else{
            node.children.map(c=>t(c,`${temp},${c.city}`))
        }
    }
    t(province)
    return result
}

data.reduce((pre,cur)=>pre.concat(getAreasInProvince(cur)),[])

看了下,我来写一个ts版本的吧,很简洁,望采纳

type Data = {
  city: string;
  children?: Data;
}[];

function get(data: Data, prefix: string = ""): string[] {
  const list: string[] = [];
  data.forEach(({ city, children }) => {
    const val = prefix ? `${prefix},${city}` : city;
    if (children?.length) {
      list.push(...get(children, val));
    } else {
      list.push(val);
    }
  });
  return list;
}

js

function get(data, prefix) {
  const list = [];
  data.forEach(({ city, children }) => {
    const val = prefix ? `${prefix},${city}` : city;
    if (children?.length) {
      list.push(...get(children, val));
    } else {
      list.push(val);
    }
  });
  return list;
}

/*** 测试开始 */
const data: Data = [
  {
    city: "浙江",
    children: [
      {
        city: "宁波",
        children: [
          {
            city: "鄞州区",
            children: [],
          },
          {
            city: "江北区",
            children: [],
          },
        ],
      },
      {
        city: "杭州",
        children: [
          {
            city: "富阳",
            children: [],
          },
          {
            city: "上城区",
            children: [],
          },
        ],
      },
    ],
  },
  {
    city: "上海",
    children: [
      {
        city: "黄浦区",
        children: [],
      },
    ],
  },
];

console.log(get(data));
data2 = data.reduce((r,p)=>(k='children',(p[k].length?p[k]:['']).map(c=>(c[k]?.length?c[k]:['']).map(z=>r.push([p.city,c.city,z.city]+''))),r),[])

我这边想法就是用flatMap去做

const result =
    data
    .flatMap(function flatMap(item) {
        const parentPath = item.parentPath ?? [];
        const currentPath = [...parentPath, item.city];
        if (item.children.length) {
            return item.children
                .map(item => ({
                    ...item,
                    parentPath,
                    parentPath: currentPath
                }))
                .flatMap(flatMap);
        }
        return [currentPath]
    })
    .map(item => item.join(','));
const getAreaList = (data)=>{
  const ans = [];
  const dfs = (children,path)=>{
      children.forEach((child)=>{
        const currentPath = [...path,child.city];
          child.children.length?dfs(child.children,currentPath):ans.push(currentPath);
      });
  }
  dfs(data,[]);
  return ans.map(arr=>arr.join(","));
}
let temp = "";
// 递归
function dg(data, pre = "") {
    data.forEach((item) => {
        let str = pre + item.city + ",";
        if (item.children.length > 0) {
            dg(item.children, str);
        } else {
            temp += str + "#";
            str = "";
        }
    });
}
dg(data);
let arr = temp.split(",#");
arr.pop();

优雅,不只是行数少。

interface IData {
  city: string;
  children: IData[];
}

const flatTree = (data: IData): string[] => {
  if (data.children.length === 0) {
    return [data.city];
  }
  return data.children
    .flatMap((child) => flatTree(child))
    .map((l) => [data.city, l].join(","));
};
console.log(data.flatMap((d) => flatTree(d)));
function transform(arr) {
    var ret = [];
    var values = [];
    var stack = arr.slice();
    var depth = [stack.length];
    while (stack.length) {
        var top = stack.shift();
        values.push(top.city);
        if (top.children.length) {
            stack.unshift.apply(stack, top.children);
            depth.push(top.children.length);
        } else {
            ret.push(values.join());
            do {
                values.pop();
            } while (--depth[depth.length - 1] === 0 && !depth.pop());
        }
    }
    return ret;
}
console.dir(transform(data));
推荐问题
宣传栏