Re: sort array by value in it
by dragonchild (Archbishop) on May 04, 2004 at 14:31 UTC
|
I'd change your code slightly to make your array into an array of hashes.
@lines = map {
/(\/\w+\/\w+)\s+\w+\s+\d+\s+\d+\s+(\d+)\s+(\d+)%/;
{
volume => $1,
available => $2,
free => 100 - $3,
}
} split /\n/, $space{ $host };
# This is the sorting line!
@lines = sort { $a->{available} <=> $b->{available} } @lines;
push @out, "$host:$_->{volume} $_->{available} $_->{free}%" for
+@lines;
------
We are the carpenters and bricklayers of the Information Age.
Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose
| [reply] [d/l] |
|
|
now i getting this funny looking warnings
host:volume available(MB) %free
Use of uninitialized value in subtraction (-) at freespace line 43.
Use of uninitialized value in subtraction (-) at freespace line 43.
Use of uninitialized value in numeric comparison (<=>) at freespace li
+ne 50.
Use of uninitialized value in numeric comparison (<=>) at freespace li
+ne 50.
Use of uninitialized value in numeric comparison (<=>) at freespace li
+ne 50.
Use of uninitialized value in numeric comparison (<=>) at freespace li
+ne 50.
Use of uninitialized value in concatenation (.) or string at freespace
+ line 52.
Use of uninitialized value in concatenation (.) or string at freespace
+ line 52.
Use of uninitialized value in concatenation (.) or string at freespace
+ line 52.
Use of uninitialized value in concatenation (.) or string at freespace
+ line 52.
149.153.130.11:/dev/hda3 10168 80%
149.153.130.11:/dev/hda2 84 90%
1 149.153.130.11: 100%
2 149.153.130.11: 100%
Use of uninitialized value in subtraction (-) at freespace line 43.
Use of uninitialized value in subtraction (-) at freespace line 43.
Use of uninitialized value in numeric comparison (<=>) at freespace li
+ne 50.
Use of uninitialized value in numeric comparison (<=>) at freespace li
+ne 50.
Use of uninitialized value in numeric comparison (<=>) at freespace li
+ne 50.
Use of uninitialized value in numeric comparison (<=>) at freespace li
+ne 50.
Use of uninitialized value in concatenation (.) or string at freespace
+ line 52.
Use of uninitialized value in concatenation (.) or string at freespace
+ line 52.
Use of uninitialized value in concatenation (.) or string at freespace
+ line 52.
Use of uninitialized value in concatenation (.) or string at freespace
+ line 52.
149.153.130.23:/dev/hda3 10168 80%
149.153.130.23:/dev/hda2 84 90%
3 149.153.130.23: 100%
4 149.153.130.23: 100%
also the lines numbered 1 2 3 4 above shouldnt be appearing
where lines 43 50 and 52 are
@lines = map {
/(\/\w+\/\w+)\s+\w+\s+\d+\s+\d+\s+(\d+)\s+(\d+)%/;
{
43 volume => $1,
available => $2,
free => 100 - $3,
}
} split /\n/, $space{ $host };
#This is the sorting line!
50 @lines = sort { $b->{available} <=> $a->{available} } @lines;
52 push @out, "$host:$_->{volume} $_->{available} $_->{free
+}%" for @lines;
| [reply] [d/l] [select] |
|
|
| [reply] |
|
|
|
|
Re: sort array by value in it
by demerphq (Chancellor) on May 04, 2004 at 16:17 UTC
|
This is a fairly common problem. The solution is to not use a string as a record, but to use a composite data type like an array or a hash as the record, sort that, and then construct your string from the record when its needed. The below is a version of this, where the string is actualyl part of the record. We sort the list of records, and then extract the strings from the resulting set.
@lines = split(/\n/,$space{ $host });
shift @lines;
my @recs;
foreach $disk_used (@lines)
{
$_ = $disk_used;
if (/(\/\w+\/\w+)\s+\w+\s+\d+\s+\d+\s+(\d+)\s+(\d+)%/ )
{
$free = 100-$3;
push @recs,[$host,$1,$2,$free,"$host:$1 $2 $free%"
+];
}
}
@out=map { $_->[-1] } sort { $b->[3] <=> $a->[3] } @recs;
HTH
---
demerphq
First they ignore you, then they laugh at you, then they fight you, then you win.
-- Gandhi
| [reply] [d/l] [select] |
|
|
host:volume available(MB) %free
149.153.130.23:/dev/hda3 10168 80%
149.153.130.23:/dev/hda2 84 90%
it didnt give me back the values for the first address i went to..???? | [reply] [d/l] |
|
|
doh!!!!!
forgot to move the declaration of the @recs outside the loop...
tanx for all your help twas greatly appreciated...
| [reply] |
Re: sort array by value in it
by Limbic~Region (Chancellor) on May 04, 2004 at 15:55 UTC
|
#!/usr/bin/perl
use strict;
use warnings;
my @data;
while ( <DATA> ) {
next if /^host:volume/;
chomp;
my @field = $_ =~ /^([^:]+):([^\s]+)\s+(\d+)\s+(\d+)/;
push @data, \@field;
}
for ( sort { $data[$a]->[2] <=> $data[$b]->[2] } 0 .. $#data ) {
print join "\t" , @{ $data[$_] };
print "\n";
}
__DATA__
host:volume available(MB) %free
10.100.200.1:/dev/hda3 10168 80%
10.100.200.1:/dev/hda2 84 90%
10.100.200.2:/dev/hda3 10168 80%
10.100.200.2:/dev/hda2 84 90%
Cheers - L~R | [reply] [d/l] |
|
|
what i mean is: below is the sorted output
host:volume available(MB) %free
10.100.200.1:/dev/hda3 10168 80%
10.100.200.2:/dev/hda3 10168 80%
10.100.200.2:/dev/hda2 84 90%
10.100.200.1:/dev/hda2 84 90%
i have an array containg multiple lines like this one
10.100.200.1:/dev/hda3  10168 80%
and i want to sort it on the value of the available field | [reply] [d/l] |
|
|
Anonymous Monk,
Did you try the program? All you would have to do is swap $a and $b. I do not remember you saying you wanted it in descending order.
Cheers - L~R
| [reply] |
|
|
|
|
|