Stream merge: Difference between revisions
Content added Content deleted
Line 1,474: | Line 1,474: | ||
</pre> |
</pre> |
||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
===Merge two streams=== |
|||
Optimized for clarity and simplicity, not performance. |
|||
assumes two files containing sorted integers separated by newlines |
assumes two files containing sorted integers separated by newlines |
||
<lang nim>import streams,strutils |
<lang nim>import streams,strutils |
||
Line 1,487: | Line 1,488: | ||
for line in stream2.lines: |
for line in stream2.lines: |
||
echo line</lang> |
echo line</lang> |
||
===Merge N streams=== |
|||
{{trans|Phix}} |
|||
Of course, as Phix and Nim are very different languages, the code is quite different, but as Phix, we use a priority queue (which is provided by the standard module <code>heapqueue</code>. We work with files built from the “Data” constant, but we destroy them after usage. We have also put the whole merging code in an procedure. |
|||
<lang Nim>import heapqueue, os, sequtils, streams |
|||
type |
|||
Source = tuple[stream: Stream; line: string] |
|||
SourceHeap = HeapQueue[Source] |
|||
# Comparison of sources. Needed for the heap to sort the sources by line contents. |
|||
proc `<`(a, b: Source): bool = a.line < b.line |
|||
proc add(heap: var SourceHeap; stream: Stream) = |
|||
## Add a stream to the heap. |
|||
if stream.atEnd: |
|||
stream.close() |
|||
else: |
|||
heap.push((stream, stream.readLine())) |
|||
proc merge(inStreams: seq[Stream]; outStream: Stream) = |
|||
## Merge the input streams into an output stream. |
|||
# Initialize the heap. |
|||
var heap: SourceHeap |
|||
for stream in inStreams: |
|||
heap.add(stream) |
|||
# Merging loop. |
|||
while heap.len > 0: |
|||
let (stream, line) = heap.pop() |
|||
outStream.writeLine line |
|||
heap.add(stream) |
|||
when isMainModule: |
|||
const |
|||
Data = ["Line 001\nLine 008\nLine 017\n", |
|||
"Line 019\nLine 033\nLine 044\nLine 055\n", |
|||
"Line 019\nLine 029\nLine 039\n", |
|||
"Line 023\nLine 030\n"] |
|||
Filenames = ["file1.txt", "file2.txt", "file3.txt", "file4.txt"] |
|||
# Create files. |
|||
for i, name in Filenames: |
|||
writeFile(name, Data[i]) |
|||
# Create input and output streams. |
|||
let inStreams = Filenames.mapIt(Stream(newFileStream(it))) |
|||
let outStream = Stream(newFileStream(stdout)) |
|||
# Merge the streams. |
|||
merge(inStreams, outStream) |
|||
# Clean-up: delete the files. |
|||
for name in Filenames: |
|||
removeFile(name)</lang> |
|||
{{out}} |
|||
<pre>Line 001 |
|||
Line 008 |
|||
Line 017 |
|||
Line 019 |
|||
Line 019 |
|||
Line 023 |
|||
Line 029 |
|||
Line 030 |
|||
Line 033 |
|||
Line 039 |
|||
Line 044 |
|||
Line 055</pre> |
|||
=={{header|Perl}}== |
=={{header|Perl}}== |