在 node.js 中将两个包含有序数据的流合并为一个流
Merge two streams containing ordered data into one stream in node.js
我是 node.js 的新手。问题是从 2 个(或更多)已排序数据的流中读取,并生成其中的 "sorted merge" 个。
例如:
Stream A: 1 5 6 8
Stream B: 2 3 4 7
========================
Result: 1 2 3 4 5 6 7 8
在 C++ 中/Java/C# 这有一个非常明显的解决方案,例如:
BufferedReader[] readers = new BufferedReader[2];
String[] lines = new String[2];
// fill lines with initial values from both readers
// ...
while (true) {
int earliestIndex = -1;
// ....
// determine earliestIndex by looping over lines and comparing them
if (earliestIndex < 0) break;
String line = lines[earliestIndex];
// do something with line
System.out.println(line);
// advance reader
lines[earliestIndex] = readers[earliestIndex].readLine();
}
但在node中,这似乎相当困难。有任何想法吗?
这是我最终想出的解决方案。我正在使用 node-line-reader 逐行读取流(文件流,但这可以很容易地更改):
var LineReader = require('node-line-reader').LineReader;
var files = ['c:\temp\1.txt', 'c:\temp\2.txt'];
var readers = [];
var lines = [];
var readWhile = function (done) {
var earliestIndex = -1;
var earliest = MAX_VALUE;
for (i = 0; i < lines.length; i++) {
var l = lines[i];
var value = parseInt(l);
if (value < earliest) {
earliest = value;
earliestIndex = i;
}
}
if (earliestIndex < 0) {
done();
return;
}
var line = lines[earliestIndex];
console.log('Read from ' + files[earliestIndex] + ': ' + line);
readers[earliestIndex].nextLine(function (err, line) {
if (err) throw err;
lines[earliestIndex] = line;
process.nextTick(function () {
readWhile(done);
});
});
}
new Promise(function (success, error) {
for (i = 0; i < files.length; i++) {
var reader = new LineReader(files[i]);
readers.push(reader);
new Promise(function (success, failure) {
reader.nextLine(function (err, line) {
if (err) failure(err);
lines.push(line);
success();
});
}).then(function (data) {
if (lines.length == files.length) success();
});
}
}).then(function (data) {
return new Promise(function (success, failure) {
readWhile(success);
});
}).then(function() {
console.log('All done');
}, function (err) {
console.log('Error: ' + err);
});
我是 node.js 的新手。问题是从 2 个(或更多)已排序数据的流中读取,并生成其中的 "sorted merge" 个。 例如:
Stream A: 1 5 6 8
Stream B: 2 3 4 7
========================
Result: 1 2 3 4 5 6 7 8
在 C++ 中/Java/C# 这有一个非常明显的解决方案,例如:
BufferedReader[] readers = new BufferedReader[2];
String[] lines = new String[2];
// fill lines with initial values from both readers
// ...
while (true) {
int earliestIndex = -1;
// ....
// determine earliestIndex by looping over lines and comparing them
if (earliestIndex < 0) break;
String line = lines[earliestIndex];
// do something with line
System.out.println(line);
// advance reader
lines[earliestIndex] = readers[earliestIndex].readLine();
}
但在node中,这似乎相当困难。有任何想法吗?
这是我最终想出的解决方案。我正在使用 node-line-reader 逐行读取流(文件流,但这可以很容易地更改):
var LineReader = require('node-line-reader').LineReader;
var files = ['c:\temp\1.txt', 'c:\temp\2.txt'];
var readers = [];
var lines = [];
var readWhile = function (done) {
var earliestIndex = -1;
var earliest = MAX_VALUE;
for (i = 0; i < lines.length; i++) {
var l = lines[i];
var value = parseInt(l);
if (value < earliest) {
earliest = value;
earliestIndex = i;
}
}
if (earliestIndex < 0) {
done();
return;
}
var line = lines[earliestIndex];
console.log('Read from ' + files[earliestIndex] + ': ' + line);
readers[earliestIndex].nextLine(function (err, line) {
if (err) throw err;
lines[earliestIndex] = line;
process.nextTick(function () {
readWhile(done);
});
});
}
new Promise(function (success, error) {
for (i = 0; i < files.length; i++) {
var reader = new LineReader(files[i]);
readers.push(reader);
new Promise(function (success, failure) {
reader.nextLine(function (err, line) {
if (err) failure(err);
lines.push(line);
success();
});
}).then(function (data) {
if (lines.length == files.length) success();
});
}
}).then(function (data) {
return new Promise(function (success, failure) {
readWhile(success);
});
}).then(function() {
console.log('All done');
}, function (err) {
console.log('Error: ' + err);
});