6
收藏
评论

第一篇文章:我曾经写过的糟糕代码

想把小程序文章功能当作博客,第一篇文章用来警醒自己。

第一篇博文主要目的不是分享,是用来警醒自己。
17 年为一个写了 154 行糟糕的代码来实现一个需求,而别人用 16 行实现了。

为什么用文章功能写博客

准备找个地方写写个人博客,懒得自己搭,因为以后和现在大部分的工作经验都会和小程序有关,打算用开发者社区的文章功能试一下。

顾虑

为了给大家创造一个良好的经验分享交流平台,我们新增了“文章分享”的模块,希望大家可以将设计、开发和运营的小程序经验分享给更多的用户,将大家平时积累的经验分享出来,也沉淀下来。

官方对文章的定义是围绕小程序的,会有很多文章是和小程序不相关的,不知道官方对这样的文章是怎样的态度,不行请告知。

154 行和 16 行代码

  • 问题,把下面的数据生成树形结构
const all = [
  'unarchive/',
  'unarchive/dsa/',
  'unarchive/dsas/',
  'unarchive/dsa/dsfgdf/',
  'unarchive/dsa/fdsf/',
  '新建文件夹/',
  '/546d573777106.cdr',
  '/546d573867eeb.jpg',
  '/unarchive/546d57377710.cdr',
  '/unarchive/546d573867ee.jpg',
  '/unarchive/dsa/546d5737771.cdr',
  '/unarchive/dsa/546d573867e.jpg',
  '/unarchive/dsa/dsfgdf/546d573867eeb.jpg',
  '/unarchive/dsa/fdsf/546d573777106.cdr',
  '/unarchive/dsa/fdsf/546d573867eeb.jpg',
  '/新建文件夹/zip.js',
];
  • 17 年刚学 js 写的 154 行代码
//把地址炸开,炸成数组
function bangData(src){
  var back_src = [];
  var arr = Array.from(src);
  var index_arr = [];
  var str;
  //去头部的“/”
  if(src.indexOf("/") == 0){
    back_src.push("/");
    arr.shift();
  }
  //去尾部的“/”
  if(src.lastIndexOf("/") == src.length - 1){
    arr.pop();
    // console.log("into",arr);
  }
  //创建下面切片会使用的下标的数组
  index_arr.push(-1);
  arr.forEach(function(c,i){
    if(c == "/"){
      index_arr.push(i);
    }
  })
  index_arr.push(arr.length);
  //给返回数组创建元素
  for(var i = 0; i < index_arr.length - 1; i ++){
    // console.log("into",index_arr,back_src);
    str = arr.slice(index_arr[i] + 1,index_arr[i + 1]).reduce(function(p,c){
      return p + c;
    });
    back_src.push(str);
  }
  return back_src;
}

//取得地址中的最大长度
function getMostLen(data){
  var most_len = 0;
  data.forEach(function(c,i){
    if(c.length > most_len){
      most_len = c.length;
    }
  })
  return most_len;
}

//判断是否为文件夹
function isDirctory(src){
  var value = false;
  if(src.lastIndexOf("/") == src.length - 1){
    value = true;
  }
  return value;
}


//json 传入数组对象以添加children
function creatClass(json,data,len,all){
  var class_dirc_data = [];
  var class_data = data.filter(function(c,i){
    if(c.length == len){
      var value = isDirctory(all[i]);
      class_dirc_data.push(value);
    }
    return c.length == len;
  });
  if(len == 1){
    class_data.forEach(function(c,i){
      json[json.length] = {
        label : c[0],
        isdirctory : class_dirc_data[i],
        children : [],
      }
    });
        var value = data.some(function(c){
      return c[0] == "/";
    });
    if(value) {
      json[json.length] = {
        label : "/",
        isdirctory : true,
        children : [],
      }
    }
  }else{
    class_data.forEach(function(current,index){
      addJsonObj(json,current,index,len,class_dirc_data);					
    })
  }	
  return json;
}

function addJsonObj(json,current,index,len,class_dirc_data){
  var parent_src;//用以暂时保存某一级的地址,记录下一次的父地址
  var haveIt ;
  var obj;
  json.some(function(c,i){
    var value = c.label == current[0];
    if(value){
      parent_src = c;
      haveIt = true;
    }
    return value;
  });
  for(var j = 1; j < len - 1; j++){
    haveIt = parent_src.children.some(function(c,i){
      var value = c.label == current[j];
      if(value){
        // console.log("into",parent_src);
        parent_src = c;
      }
      return value;
    });
    if(!haveIt){
      break;
    }
  }
  if(haveIt){
    obj = {
      label : current[len-1],
      isdirctory : class_dirc_data[index],
      children : [],
    }
    // console.log("into1",obj,current,parent_src);						
    parent_src.children.push(obj);						
  } else {
    obj = {
      label : current[j],
      isdirctory : true,
      children : [],
    }
    // console.log("into",obj);
    //对象不存在时进行创建,之后再次调用
    parent_src.children.push(obj);
    addJsonObj(json,current,index,len,class_dirc_data);	
  }
}

//创建json_data
function creatJson(data){
  var return_json = [];
  var bang_all = data.map(function(c,i){
    return bangData(c);
  });
  console.log(bang_all);
  var most_len = getMostLen(bang_all);
  console.log(most_len);
  for(var i = 1; i <= most_len; i++){
    // return_json = creatClass(return_json,bang_all,i,all);
    creatClass(return_json,bang_all,i,data);
  }
  console.log(return_json);
}
creatJson(all);

  • 老师的 16 行代码

var files = {};

function formatFloder(path) {
    var cur = files;
    path.split("/").slice(1).forEach(function(elem, index) {
        if (elem) {
            cur[elem] = cur[elem] || {isDir: elem.indexOf(".") == -1,name: elem};
            cur = cur[elem];
        }
    });
}

all.forEach(function(path) {
    path = path[0] != "/" ? "/" + path : path;
    formatFloder(path);
})

  • 现在(2019-03-10)的 22 行代码

function buildPathTree (pathArray) {
    const treeData = pathArray.reduce((prev, c) => {
        const rawNodes = c.split('/')
        const rawNodes2 = c.startsWith('/') ? rawNodes.slice(1) : rawNodes 
        const nodes = c.endsWith('/') ? rawNodes2.slice(0, -1) : rawNodes2

        // 修改 prev 添加节点
        nodes.reduce((prevNode, name) => {
            if (prevNode[name]) {
                return prevNode[name]
            } else {
                const isDir = name.includes('.')
                prevNode[name] = { isDir, name }
                return prevNode[name]
            }
        }, prev)

        return prev
    }, {})

    return treeData
}


期望

  • 希望这篇文章能让自己在偶尔得意的时候谦逊起来。
最后一次编辑于  03-11  (未经腾讯允许,不得转载)
复制链接赞 6收藏投诉评论

4 个评论

  • raphealguo
    raphealguo
    03-11

    加油!


    因为目前社区聚集的是小程序开发者,所以我们会更加鼓励作者来分享小程序知识和Web前端知识,这样会让你的文章得到更多人的关注。 从你的文章当中,我们需要加一下代码行号的显示的需求。

    03-11
    赞同 1
    回复
  • 不要说话
    不要说话
    03-11

    我进社区看的第一篇文章,看到你的进步,不断进取

    03-11
    赞同
    回复 1
    • 金池
      金池
      03-12

      谢谢

      03-12
      回复
  • 浩
    03-12

    也不是说行数短就好,还是看运行效率快还有代码容易维护才是真的好吧

    03-12
    赞同
    回复