Stream merge: Difference between revisions

Line 1,474:
</pre>
=={{header|Nim}}==
===Merge two streams===
optimizedOptimized for clarity and simplicity, not performance.
assumes two files containing sorted integers separated by newlines
<lang nim>import streams,strutils
Line 1,487 ⟶ 1,488:
for line in stream2.lines:
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}}==
Anonymous user