I need to read a file line by line, and change a variable accordingly. I would normally write this in PHP... but I decided to take the challenge.
I wrote:
fs = require('fs');
Lazy = require('lazy');
path = require('path');
files = fs.readdirSync('.');
var software = {};
files.forEach( function(fileName){
var m;
if( m = fileName.match(/^(.*)\.txt$/) ){
name = m[1];
console.log("Processing file: " + fileName);
software[name] = {};
console.log("Software 1: %j",software);
var section = 'unset';
new Lazy(fs.createReadStream(fileName)).lines.forEach(
function(line){
var m;
line = line + '';
if( m = line.match(/^([a-zA-Z_]*):$/)){
section = m[1];
software[name][section] = '';
console.log("Switching to section " + m[1]);
console.log("Software 2: %j",software);
} else if (line == '.'){
section = 'unset'
} else if (line == ''){
section = 'unset'
} else {
console.log("LINE: " + line) ;
software[name][section] = software[name][section] + line + "\n";
console.log("Software 3: %j",software);
}
}
);
}
});
console.log("Software 4: %j",software);
Apart from the code being very ugly and very unoptimised, I am having trouble as when the last line prints, the "software" variable is not YET populated! I am guessing Lazy is asyncronous. So, it basically works, but "at some point later". This is great, but... where do I write code when that important cycle, that fills in the software variable, is actually finished?!?
As requested: data to play with!
simply create "something.txt" and write:
name:
Name 1
.
Option 1:
Value 1
.
Option 2:
Value 2
.
Option 3:
Multi
Line
Value
.
Another_section:
Again
.
Merc.
The instances of Lazy returned by the library are EventEmitters, and it emits en event called pipe when a "set" of operations is complete:
new Lazy(
...
).on('pipe', function() {
// all done
});
Modifying your code to use this event results in (the only change is near the bottom):
fs = require('fs');
Lazy = require('lazy');
path = require('path');
files = fs.readdirSync('.');
var software = {};
files.forEach( function(fileName){
var m;
if( m = fileName.match(/^(.*)\.txt$/) ){
name = m[1];
console.log("Processing file: " + fileName);
software[name] = {};
console.log("Software 1: %j",software);
var section = 'unset';
new Lazy(fs.createReadStream(fileName)).lines.forEach(
function(line){
var m;
line = line + '';
if( m = line.match(/^([a-zA-Z_]*):$/)){
section = m[1];
software[name][section] = '';
console.log("Switching to section " + m[1]);
console.log("Software 2: %j",software);
} else if (line == '.'){
section = 'unset'
} else if (line == ''){
section = 'unset'
} else {
console.log("LINE: " + line) ;
software[name][section] = software[name][section] + line + "\n";
console.log("Software 3: %j",software);
}
}
).on('pipe', function() {
console.log("Software 4: %j",software);
});
}
});
[Edit] To answer your question regarding how I found this info:
I did indeed check out the source file for the project; I knew the library had a sum method that could be chained to instances of Lazy to sum up everything at the end; the code for that method calls foldr, and the code for that method listens for an event called pipeName, which is defaulted in line 22 as pipe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With