我正在努力获取子文件的总和。假设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))
此外,欢迎提供任何改进此代码的建议。
答案 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'))