鍍金池/ 問答/數(shù)據(jù)分析&挖掘  C  HTML/ js 遍歷嵌套數(shù)組

js 遍歷嵌套數(shù)組

需求:用最優(yōu)性能的方法將嵌套數(shù)組轉(zhuǎn)化為一維數(shù)組。

var data = [
  {
    id: '1', 
    title: 'A1', 
    child: [
      {
        id: '4',
        title: 'B1'
      }
    ]
  },
  { 
    id: '2', 
    title: 'A2',
    child: [
      {
        id: '5',
        title: 'B2',
        child: [
          {
            id: '7',
            title: 'C1',
            child: [
              {
                id: '8',
                title: 'D1'
              }
            ]
          }
        ]
      },
      {
        id: '6',
        title: 'B3'
      }
    ] 
  },
  { 
    id: '3', 
    title: 'A3' 
  }
]

// 結(jié)果應(yīng)該為:
// [{id:'1',title:'A1'},{id:'4',title:'B1'},{id:'2',title:'A2'},{id:'5',title:'B2'}...]

請(qǐng)各路大俠賜教!

回答
編輯回答
夢(mèng)囈

var nest_result=[];
function arrNestToNonNest(arr){

for(let item of arr){
    nest_result.shift({"id":item.id,"title":item.title})
    if(item.hasOwnProperty("child")){
        arrNestToNonNest(item.child)
    }
}

}
arrNestToNonNest(data)

2017年3月13日 05:30
編輯回答
假灑脫

可能并不是最優(yōu),但很清真(跑

function flattern(data) {
  return data.reduce((iter, val) => {
    let {id, title} = val;
    let com_arr = [...iter, {id, title}];
    return val.child ? [...com_arr, ...flattern(val.child)] : com_arr;
  }, []);
}

let result = flattern(data);
console.log(result);
2017年12月31日 12:48
編輯回答
傻叼

大概就是個(gè)廣度優(yōu)先算法嘛...

var result = [];    // 存放結(jié)果
var queue = [data]; // 用于遍歷
var item;           // 臨時(shí)值
// 從隊(duì)列里取出要轉(zhuǎn)換的數(shù)據(jù)數(shù)組
while (item = queue.shift()) {
    item.forEach(i => {
        // 遍歷數(shù)組,轉(zhuǎn)換數(shù)據(jù),放入結(jié)果中
        result.push({
            id: i.id,
            title: i.title,
        });
        // 如果有子數(shù)據(jù)的,放到隊(duì)列最后等待處理
        i.child && queue.push(i.child);
    })
}

emm...看了下評(píng)論是需要深度遍歷...都寫上吧。

var result = [];    // 存放結(jié)果
(function traverse(node) {
    node.forEach(i => {
        result.push({
            id: i.id,
            title: i.title,
        });
        // 有子數(shù)據(jù)的先遍歷子數(shù)據(jù)
        i.child && traverse(i.child)
    })
})(data);
2018年4月3日 13:16
編輯回答
忠妾

樓上的方法都不錯(cuò)了,這個(gè)性能也就這樣的。

2017年1月11日 09:34
編輯回答
殘淚

這是一個(gè)遍歷樹型結(jié)構(gòu)的問題,可以參閱:使用遞歸遍歷并轉(zhuǎn)換樹形數(shù)據(jù),文中講到了用遞歸實(shí)現(xiàn)的深度遍歷,也講到了用隊(duì)列實(shí)現(xiàn)的廣度遍歷。

深度遍歷和廣度遍歷的結(jié)果順序會(huì)有所不同,樓上兩位都是遞歸實(shí)現(xiàn)(深度),下面給個(gè)廣度的示例:

function gothrough(data) {
    const queue = [...data];
    const result = [];
    while (true) {
        const next = queue.shift();
        if (!next) {
            break;
        }
        result.push({
            id: next.id,
            title: next.title
        });
        if (Array.isArray(next.child)) {
            queue.push(...next.child);
        }
   }

   return result;
}

代碼還可以簡潔一些,但性能可能會(huì)略差一點(diǎn)

function gothrough(data) {
    let next = [...data];
    const result = [];
    while (next.length) {
        result.push(...next.map(m => ({ id: m.id, title: m.title })));
        next = next
            .filter(m => Array.isArray(m.child))
            .reduce((all, m) => [...all, ...m.child], []);
    }
    return result;
}

clipboard.png

2017年9月25日 02:12
編輯回答
喵小咪
(function(_data,_list){
    function t_whill(data){
        for(let info of data){
            if('child' in info){
                t_whill(info['child']);
                delete info['child'];
            }
            _list.push(info);
        }
    }
    t_whill(_data,_list);
    log(_list);
})(data,[]);

圖片描述

2017年1月6日 03:56
編輯回答
哎呦喂
function TreeToArray(data,list) {
    var i = 0, len = data.length, list = list || [];
    for (; i < len;) {
        var item = data[i++], child = item.child;
        if (child) {
            delete item.child;
            list.push(item);
            arguments.callee(child, list);
        } else {
            list.push(item);
        }
    }
}

var list = [];
TreeToArray(data, list);
console.log(JSON.stringify(list));
2018年7月17日 18:53