如何递归修改下面结构的'_children'属性名改为'children'
发布于 7 年前 作者 gyj1278 5265 次浏览 来自 问答
var data = {
  '_children': [{
    '_children': [{
      '_children': []
    },
    {
      '_children': []
    },
    {
      '_children': []
    },
    {
      '_children': []
    }]
  },
  {
    '_children': []
  },
  {
    '_children': []
  },
  {
    '_children': []
  }]
}

function dataFormat(data) {
  if (data._children) {
    data.children = data._children
    delete data._children
    if (data.children.length) {
      _.each(data.children, (item) => {
        dataFormat(item)
      })
    }
  }
}

我写了上面的方法,结果可以,但是我对自己写的这个方法比较迷惑: 当数据量大的时候,这种方法是否可行? 这种方法属于递归吗? 对递归比较迷惑,似乎这个方法中没写递归的终止条件什么的?

18 回复
  • 可行
  • 属于,是用递归进行树遍历的标准做法
  • 这里的终止条件是children里没有元素为止,控制终止的语句是上面的if (data.children.length)

@dislido 有没有更好的办法?总觉得把属性赋值给另外一个属性,再删除原属性有点膈应。

@gyj1278 没有特殊需要的话,可以不用管原属性,一个引用放在那里也不占多少空间

我倒感觉用 “_children” 这个名字更好,加个前缀专门用来放下级节点,区别于一般业务属性。。

这个效率偏低,哥给你一个高效的

let str = JSON.stringify(data) 
/*
"{"_children":[{"_children":[{"_children":[]},{"_children":[]},{"_children":[]},{"_children":[]}]},{"_children":[]},{"_children":[]},{"_children":[]}]}"
*/
str = str.replace(/{"_children":/g, '{"children":')
data = JSON.parse(str)

😄 拿走不谢

=================================== My Blog : http://39.108.115.22

@fuxingZhang 只需要把 "_"去掉就ok了

来自酷炫的 CNodeMD

@zswnew 不行的,会误删不该删的,替换_children都是不对的,比如值是[ ‘1231_children12313’,…],考虑全面一点

@fuxingZhang 别人题目都是这么说的

来自酷炫的 CNodeMD

@zswnew 你太死板了,又不是做题,要考虑生产实际好吗,你问问作者吧

@fuxingZhang 你的解法也会误删。

@fuxingZhang 这位老哥和我想的一样,会直接转成字符串全局替换就好

@XadillaX 👍 确实,虽然可能性已经降低到很小,但仍存在误删的可能

@myy 是的,业务上就是把’children’变为"_children",这里换了一下,大哥,你还是看的透啊。

@fuxingZhang 这个方法我知道,可是同事告诉我,如果数据量很大的话,replace可能会挂掉。

@dislido 我给的只是一个简单的例子,实际业务上可能会有很多层,每层又会有很多个节点的。

@gyj1278 对象中存储一个引用的键所占用的空间是很小的,当然对大小有要求的话还是删掉比较好。上面那个转字符串替换的,把那么大个对象遍历一下生成字符串再替换,然后又eval回去,性能明显会十分低下

@dislido 是的,转字符串的方法可靠性也不太高。

可以替换"_children":

回到顶部