sreenath has asked for the wisdom of the Perl Monks concerning the following question:
This node falls below the community's threshold of quality. You may see it by logging in.
Re: Array Sorting
by ELISHEVA (Prior) on Dec 14, 2010 at 12:03 UTC
|
Please, when you post code, surround it with <code> ... my code here ... </code> tags. Otherwise all the formatting gets lost and we can't read with any ease what you wrote.
That being said, it appears that you are confounding two very different meanings for the word "array". In one part of your code, you are viewing the line you read in as an array of comma delimited fields, i.e. @array=split(/,/ $line). In another part of your code, when you sort, you are viewing the collection of records (one per line) as an array. Perl is confused because the "array" you are sorting to put the records in age order is the array of fields. All you are doing in your sort is sorting the field values within a single record, not the records.
Human beings can handle such ambiguities well, but computer programs are much less tolerant. You can have two meanings of arrays, BUT you must use two different structures for each meaning:
- array of fields (one per line): A simple array of strings, one for each field.
- array of records: an array of array references (AoA), where each element of the array is an array reference storing a different line that you have read in.
Thus, your code should look something like this.
my @aRecords;
my $iRecord=0;
while ($line = <INPUT_FILE>) {
my @aFields = split(/,/, $line);
$aRecords[$iRecord] = \@aFields; # \@ creates an array reference
$iRecord++;
}
# now that you have read in all the lines, you can sort them
# assuming age is the second field, it will be stored at
# index 1 (fields are numbered starting at 0)
my @aSortedRecords = sort { $a->[1] <=> $b->[1] } @aRecords;
You'll need to use an array reference to accomplish this, please take a look at perllol, and possibly perlref and perldsc as well.
Update: expanded explanation of why code doesn't work and clarified description of AoA. | [reply] [d/l] [select] |
Re: Array Sorting
by jethro (Monsignor) on Dec 14, 2010 at 12:01 UTC
|
Please use <code> tags so that your script looks like a real script and '$array1' looks like '$array[1]'
Also you need to debug your program. That is relatively easy, just add a few print statements that tell you what array1 or array2 looks like
You often will see immediately where your program doesn't do what you want. For example you seem to first split for commas (quite sensible) and then afterwards for line endings (\n) which really doesn't make sense since you only read your file one line at a time.
| [reply] [d/l] |
Re: Array Sorting
by Utilitarian (Vicar) on Dec 14, 2010 at 12:06 UTC
|
First a word of advice on your formatting, you should surround code and formatted data with <code> tags as otherwise it becomes difficult to read. You had to go through a preview page and must have seen this yourself, it should look more like this:
Data
names,age
Rahul,25
Manu,36
Vijay,41
Tushar,23
Hetal,54
Binoy,19
Vikram,16
Code
$file='a.csv';
open (a,$file) || die ("couldnt open file");
while ($line=<a>){
@array=split(/,/,$line);
@array1=split(/\n/,$array[1]);
@array2=sort {$a <=> $b}(@array1);
print "@array2";
}
This is just wrong, you should use the existing Text::CSV module, however if this is home work you should do something like the following (assumes that names are unique)
- Read each line of the file into a hash of name=>agesplitting on ,
- Sort the hash by value using the Schwartzian transform(understanding how this works will enlighten you greatly)
print "Good ",qw(night morning afternoon evening)[(localtime)[2]/6]," fellow monks."
| [reply] [d/l] [select] |
Re: Array Sorting
by Corion (Patriarch) on Dec 14, 2010 at 11:30 UTC
|
You are talking about "the array", but you have at least three variables, named @array, @array1 and @array2. Which one do you mean?
Also, are you sure that what you are programming makes sense? It seems to me that your variables do not contain what you think they do. You are sorting and printing within your loop. This is most unlikely what you want if you want to sort the complete file.
| [reply] [d/l] [select] |
Re: Array Sorting
by prasadbabu (Prior) on Dec 14, 2010 at 12:08 UTC
|
Hi Sreenath,
Here is one way to read csv file and process your data. Here no need to split your data for sorting as you have done in your coding.
use strict;
use Text::CSV::Simple;
my $parser = Text::CSV::Simple->new;
my @data = $parser->read_file("d:\\prasad\\projects\\tools\\test.csv")
+;
print "Name - Age\n";
print "__________\n";
print $_->[0],' - ', $_->[1],"\n" for (sort {$a->[1] <=> $b->[1]} @d
+ata);
output:
=======
Name - Age
__________
Vikram - 16
Binoy - 19
Tushar - 23
Rahul - 25
Manu - 36
Vijay - 41
Hetal - 54
| [reply] [d/l] |
|
HI Prasad,thanks for your reply.
Is there no way I can sort ,if i split????
| [reply] |
|
| [reply] |
Re: Array Sorting
by sundialsvc4 (Abbot) on Dec 14, 2010 at 14:53 UTC
|
| |
Re: Array Sorting
by Tux (Canon) on Dec 15, 2010 at 17:07 UTC
|
Putting all the advices together, with a few changes gives me:
use strict;
use warnings;
use autodie;
use Text::CSV_XS;
my $csv = Text::CSV_XS->new ({ binary => 1, auto_diag => 1 });
open my $fh, "<:encoding(utf-8)", "a.csv";
my @hdr = @{$csv->getline ($fh)};
my @arr;
while (my $row = $csv->getline ($fh)) {
push @arr, $row;
}
local $" = "\t";
print "@hdr\n";
print "@$_\n" for sort { $a->[1] <=> $b->[1] } @arr;
Which will give you:
names age
Vikram 16
Binoy 19
Tushar 23
Rahul 25
Manu 36
Vijay 41
Hetal 54
Enjoy, Have FUN! H.Merijn
| [reply] [d/l] [select] |
|
|