As already pointed out by Anonymous, the .= effectively appends to the string.
Just to elaborate a little, consider the following (simplified) IN file:
B ... 204248 ...
A ... 204249 ...
D ... 204250 ...
C ... 204251 ...
E ... 204252 ...
A ... 204253 ...
F ... 204254 ...
C ... 204255 ...
B ... 204256 ...
If you go looking for the IDs A, B, C one after the other in
several passes (as in your original approach), the hits will
automatically be sorted by ID:
A 204249 # first pas
A 204253
B 204248 # second pass
B 204256
C 204251 # third pass
C 204255
While if you do it in one pass, checking every entry against
"if ( exists $scGeneids{$gene_id} )" to see if it's of interest, you'll
get the IDs in the order they were encountered in IN, when you print them out immediately
B 204248
A 204249
C 204251
A 204253
C 204255
B 204256
This won't be an issue, of course, in case the entries are already
sorted by ID. Otherwise, it might not be what you want.
You haven't said anything about the desired ordering of the
results, nor whether IN is already sorted... so I thought it's worth
pointing out anyway that if you wanted output similar to what your
original multi-pass approach would have produced (if you had correctly
reset the file in between passes), you could collect the results by ID
before writing them out. I.e., every time you encounter a hit, you
append the line to the respective hash entry.
In other words, after having gone through the file, $scGeneids{A} will
hold a long string with all A records, $scGeneids{B} all B
records, and so on, so you can nicely print them out in sorted order.
The same result could have been achieved by collecting the records in arrays
(i.e. @{ $scGeneids{$gene_id} } ) and then joining them on output, but
I thought the string-append variant is a tad easier to understand...
|