Article From:https://segmentfault.com/q/1010000011698944
Question:

There are a series of arrays as follows:

var filelist = [{ name: 'a.html', path: 'src/app' }, { name: 'b.html', path: 'src/app' }, { name: 'c.html', path: 'src/app/com' }, { name: 'd.html', path: 'src/acc' }, { name: 'e.html', path: 'src/acc' }]

How to use JavaScript to traverse it into a file tree format:
as follows

    [{
        title: 'src',
        children: [{
            title: 'app',
            children: [{
                title: 'a.html'
            }, {
                title: 'b.html',
            }, {
                title: 'com',
                children: [{
                    title: 'c.html'
                }
            }]
        }, {
            title: 'acc',
            children: [{
                title: 'c.html'
            }, {
                title: 'd.html',
            }]
        }]
    }]
├── src
│   ├── app
│      ├── index.html
│      ├── a.html
│      ├── com
│         ├── b.html

Answer 0:

It’s just for you to write filelist format.
See the following code for details.

var filelist = [
  { name: 'a.html', path: 'src/app' },
  { name: 'b.html', path: 'src/app' },
  { name: 'c.html', path: 'src/app/com' },
  { name: 'd.html', path: 'src/acc' },
  { name: 'e.html', path: 'src/acc' }
]

function structuring(arr) {
  var rtn = []
  arr.forEach((el, i) => {
    var keys = el.path.split('/')
    keys.push(el.name)
    var tmp = rtn;
    keys.forEach((key, i) => {
      if (!findTitle(tmp, key).length) {
        if (key.indexOf('.html') > -1) {
          tmp.push({ title: key })
        } else {
          tmp.push({ title: key, children: [] })
          tmp = findTitle(tmp, key)[0].children
        }
      } else {
        tmp = findTitle(tmp, key)[0].children
      }
    });
  })
  return rtn
}

function findTitle(arr, title) {
  var tmp = arr.filter((v, i) => {
    return v.title === title
  })
  return tmp
}

console.log(structuring(filelist))

Answer 1:

Map should be faster.

class FileTree {
  constructor (filelist) {
    this.tree = new Map()
    if (filelist) {
      this.build(filelist)
    }
  }

  build (filelist) {
    filelist.forEach(file => {
      const path = file.path.split('/')
      let dir = path.reduce((node, p) => {
        if (!p) { return node }
        if (!node.has(p)) {
          node.set(p, new Map())
        }
        return node.get(p)
      }, this.tree)
      dir.set(file.name, new Map())
    })
  }

  values () {
    return this._genTree(this.tree)
  }

  _genTree (node) {
    return Array.from(node.entries())
      .map(([k, v]) => {
        const result = {title: k}
        if (v.size > 0) { result.children = this._genTree(v) }
        return result
      })
  }
}
var filelist = [{ name: 'a.html', path: 'src/app' }, { name: 'b.html', path: 'src/app' }, { name: 'c.html', path: 'src/app/com' }, { name: 'd.html', path: 'src/acc' }, { name: 'e.html', path: 'src/acc' }]

const fileTree = new FileTree(filelist)
console.log(JSON.stringify(fileTree.values(), null, '  '))

Answer 2:

Write a recursive function, using the space character line character and custom symbol to do it.

Similar Posts:

Link of this Article: How do you make array grouping?

Leave a Reply

Your email address will not be published. Required fields are marked *