首页 > 解决方案 > 遍历子文件并获取Javascript中内容总和的结果

问题描述

我正在努力获得子文件的总和。下面的代码当前返回总和a.txt及其所有子文件,假设内容a.txt

1
b.txt

的内容b.txt

2
c.txt

的内容c.txt

3

我还想获取b.txt所有存在的文件的总和及其所有子文件、总和c.txt及其所有子文件等等。所以输出将是:总和a.txt及其子文件是sum,总和b.txt及其子文件是sum,总和c.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))

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

标签: javascriptrecursionecmascript-6sum

解决方案


这可以看作是一个非常标准的图形搜索。您的代码开始这样做,但有几个地方可以更改以使其更容易一些。

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

我制作的代码的模拟版本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'))


推荐阅读