遍历子文件并获取Javascript中内容总和的结果

时间:2018-07-10 05:22:59

标签: javascript recursion ecmascript-6 sum

我正在努力获取子文件的总和。假设a.txt的内容为

,下面的代码当前返回a.txt及其所有子文件的总和。
1
b.txt

b.txt的内容是

2
c.txt

c.txt的内容是

3

我还要获取b.txt及其所有子文件的总和,c.txt及其所有子文件的总和,依此类推,以此类推。 。因此输出为:a.txt及其子文件的总和为sumb.txt及其子文件的总和为sumc.txt的总和其子文件为sum,依此类推...

我的下面的代码:

const fs = require('fs')
const file = 'a.txt'

let output = (file) => {
  let data = fs.readFileSync(file, 'utf8')
    .split('\n')
    .reduce((array, i) => {
      if (i.match(/.txt$/)) {
        let intArr = array.concat(output(i))
        return intArr
      } else if (i.match(/^\d+$/)) {
        array.push(parseInt(i, 10));
      }
      return array;
    }, [])

    return data
}

console.log(output(file))

const sum = output(file)

console.log(sum.reduce((a, b) => a + b, 0))

此外,欢迎提供任何改进此代码的建议。

1 个答案:

答案 0 :(得分:1)

这可以看作是标准的图形搜索。您的代码开始执行此操作,但是可以在一些地方进行更改以使其变得更简单。

以下是从特定文件开始并跟踪计数对象的深度优先搜索。该函数像解析文件一样解析文件,将数字counts添加到对象中。然后它递归。当递归展开时,会将结果子计数加到父级。最后,它返回counts对象,该对象应具有所有页面的total +子页面。为了简单起见,它不会进行任何错误检查,也不清楚如果两个孩子都引用同一个孙子,应该怎么办-应该计算两次吗?要么应该容易调整。

我制作了fs.readFileSync的模拟版本,该代码可以在摘要中运行,并且更易于查看:

// fake fs for readFileSync
let fs = {
    files: {
        "a.txt": "1\nb.txt",
        "b.txt": "2\nc.txt",
        "c.txt": "3",
        "d.txt": "2\n10\ne.txt\nf.txt",
        "e.txt": "1",
        "f.txt": "5\n7\ng.txt",
        "g.txt": "1\na.txt"
    },
    readFileSync(file) { return this.files[file]}
}

function dfs(file, counts = {}) {
    // parse a sinlge file into object
    // {totals: sum_allthenumbers, files:array_of_files}
    let data = fs.readFileSync(file, 'utf8').split('\n')
    let {total, files} = data.reduce((a, c) => {
        if(c.match(/^\d+$/)) a.total += parseInt(c)
        else if(c.match(/.txt$/)) a.files.push(c)
        return a
    },{total: 0, files:[]})

    // add the total counts for this file
    counts[file] = total      
    // recurse on children files
    for (let f of files) {
       if (counts.hasOwnProperty(f)) continue // don't look at files twice if there are cycles
        let c = dfs(f, counts) 
        counts[file] += c[f]  // children return the counts object, add childs count to parent
    }
    // return count object
    return counts 
}

console.log("original files starting with a.txt")
console.log(dfs('a.txt'))

console.log("more involved graph starts with d.txt")
console.log(dfs('d.txt'))