Re: Conditional sorting across two arrays

2006-12-12 Thread Rob Dixon

Rinku Mahesh wrote:
 Hi,

 I've two arrays of same depth (let it be 6)

 1st Array:-  @unique {11 , 23, 44, 66, 900, 1009} 2nd Array:- @occ_count {2,
 77, 22, 2, 77,29}

 Here I'm looking for a sorting mechanism with the following conditions:-

 a. Sort 2nd Array in descending order such that it should reflect
 {77,77,29,22,2,2}

 b. The values of 1st array should also change in accordance with the
 positions of elements of 2nd array such that sorting the 1st array should
 reflect {23,900,1009,44,11,66}

 23 and 900 or 11 and 66 can be interchanged but whatever value is lesser
 should appear first in the list.

 c. As there are repeatations in 2nd Array (77 and 2) there could be two
 values associated with these elements in 1st array (23/900 or 11/66). Here 23
 is lesser than 900 thus it should appear fist in the list.


 If the above explaination is confusing I'm looking for a way where every
 element of an array can be mapped to corresponding element of another array
 and as a whole both the arrays require a sorting w.r.t. 2nd array.


 Can anyone suggest an eficient way to implement same.

Hi Rinku

You need to sort a list of indices. Take a look at the code below which does
what you describe.

HTH,

Rob


use strict;
use warnings;

my @unique = (11, 23, 44, 66, 900, 1009);
my @occ_count = (2, 77, 22, 2, 77, 29);

my @idx = sort {
  $occ_count[$b] = $occ_count[$a] or
  $unique[$a] = $unique[$b]
} 0 .. $#unique;

@unique = @[EMAIL PROTECTED];
@occ_count = @[EMAIL PROTECTED];

foreach (0 .. $#unique) {
  printf %4d - %2d\n, $unique[$_], $occ_count[$_];
}

**OUTPUT**

  23 - 77
 900 - 77
1009 - 29
  44 - 22
  11 -  2
  66 -  2


--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: Conditional sorting across two arrays

2006-12-12 Thread Rob Coops

Hi Rinku,

Now I could try and explain this in my own words but I think this will help
you a lot more.

http://www.unix.org.ua/orelly/perl/advprog/ch02_02.htm

What you are looking for is a very common thing, your not the first to bump
into this problem :-)

Regards,

Rob



On 12/12/06, Rinku Mahesh [EMAIL PROTECTED] wrote:


Hi,

I've two arrays of same depth (let it be 6)

1st Array:-  @unique {11 , 23, 44, 66, 900, 1009}
2nd Array:- @occ_count {2, 77, 22, 2, 77,29}

Here I'm looking for a sorting mechanism with the following conditions:-

a. Sort 2nd Array in descending order such that it should reflect
{77,77,29,22,2,2}

b. The values of 1st array should also change in accordance with the
positions of elements of 2nd array such that sorting the 1st array should
reflect {23,900,1009,44,11,66}

23 and 900 or 11 and 66 can be interchanged but whatever value is lesser
should appear first in the list.

c. As there are repeatations in 2nd Array (77 and 2) there could be two
values associated with these elements in 1st array (23/900 or 11/66). Here
23 is lesser than 900 thus it should appear fist in the list.


If the above explaination is confusing I'm looking for a way where every
element of an array can be mapped to corresponding element of another array
and as a whole both the arrays require a sorting w.r.t. 2nd array.


Can anyone suggest an eficient way to implement same.

TIA,

Rinku



-
Everyone is raving about the all-new Yahoo! Mail beta.



Re: Conditional sorting across two arrays

2006-12-12 Thread Dr.Ruud
Rinku Mahesh schreef:

  I've two arrays of same depth (let it be 6)
 
   1st Array:-  @unique {11 , 23, 44, 66, 900, 1009}
   2nd Array:- @occ_count {2, 77, 22, 2, 77,29}
 [...]
   b. The values of 1st array should also change in accordance with
 the positions of elements of 2nd array such that sorting the 1st
 array should reflect {23,900,1009,44,11,66}  

Why then are these values not stored in an AoA? (see perldsc)

  my @x =
  ( [  11,  2]
  , [  23, 77]
  , [  44, 22]
  , [  66,  2]
  , [ 900, 77]
  , [1009, 29]
  ) ;

-- 
Affijn, Ruud

Gewoon is een tijger.

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: Conditional sorting across two arrays

2006-12-12 Thread Ovid
--- Rob Coops [EMAIL PROTECTED] wrote:

 Hi Rinku,
 
 Now I could try and explain this in my own words but I think this
 will help you a lot more.
 
 http://www.unix.org.ua/orelly/perl/advprog/ch02_02.htm
 
 What you are looking for is a very common thing, your not the first
 to bump into this problem :-)

Please don't link to copyrighted work which has been posted to the Web
in violation of said copyright.  Writing a book is hard work and unless
the author deliberately wants their book to be given away for free, we
should respect the author's desire to earn a living.

Cheers,
Ovid

--

Buy the book -- http://www.oreilly.com/catalog/perlhks/
Perl and CGI -- http://users.easystreet.com/ovid/cgi_course/

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




RE: Conditional sorting across two arrays

2006-12-12 Thread Charles K. Clarkson
Rinku Mahesh mailto:[EMAIL PROTECTED] wrote:

:   If the above explaination is confusing I'm looking for a way
: where every element of an array can be mapped to corresponding
: element of another array and as a whole both the arrays require
: a sorting w.r.t. 2nd array.

M.J. Dominus wrote three slides about an Indirect Sort which
you may find helpful. He's using two arrays of names. One for
first names, one for last names. Basically, the idea is to sort
the array indexes and then apply the sorted indexes to each array
using an array slice. (I don't know if he's right about those APL
folks.)

http://perl.plover.com/yak/hw2/samples/slide003.html


In your case, you need a numerical comparison (=) on both
arrays as opposed to a string comparison (cmp). You also require
that ties be sorted on the other array. That can be performed
within the sort. One thing I like about sorting indexes is that
you can save the sorts.

use strict;
use warnings;

# Test data
my @unique= ( 66, 23, 44, 11, 900, 1009 );
my @occ_count = (  2, 77, 22,  2,  77,   29 );

# Sort in ascending order, ascending order
# Use reverse for descending order, descending order
my @ascending_indexes =
sort {
$occ_count[$a] = $occ_count[$b]
||
   $unique[$a] = $unique[$b]

} 0 .. $#occ_count;

# Sort in descending order, ascending order
# Use reverse for ascending order, descending order
my @descending_indexes =
sort {
$occ_count[$b] = $occ_count[$a]
||
   $unique[$a] = $unique[$b]

} 0 .. $#occ_count;


# Reports
print Ascending sort then ascending sort:\n\t;
printf '%5d', $_ foreach @occ_count[ @ascending_indexes ];
print \n\t;
printf '%5d', $_ foreach @unique[ @ascending_indexes ];
print \n\n;

print Ascending sort then descending sort\n\t;
printf '%5d', $_ foreach @occ_count[ reverse @descending_indexes ];
print \n\t;
printf '%5d', $_ foreach @unique[ reverse @descending_indexes ];
print \n;

print Descending sort then descending sort:\n\t;
printf '%5d', $_ foreach @occ_count[ reverse @ascending_indexes ];
print \n\t;
printf '%5d', $_ foreach @unique[ reverse @ascending_indexes ];
print \n\n;

print Descending sort then ascending sort\n\t;
printf '%5d', $_ foreach @occ_count[ @descending_indexes ];
print \n\t;
printf '%5d', $_ foreach @unique[ @descending_indexes ];
print \n;

__END__

For larger arrays, you might want to transform one array
first.


HTH,

Charles K. Clarkson
--
Mobile Homes Specialist
Free Market Advocate
Web Programmer

254 968-8328

http://www.clarksonenergyhomes.com/

Don't tread on my bandwidth. Trim your posts.


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: Conditional sorting across two arrays

2006-12-12 Thread Paul
On Tue, December 12, 2006 6:25 am, Ovid wrote:
 --- Rob Coops [EMAIL PROTECTED] wrote:

 Hi Rinku,
 Now I could try and explain this in my own words but I think this will
help you a lot more.

 What you are looking for is a very common thing, your not the first to
bump into this problem :-)

 Please don't link to copyrighted work which has been posted to the Web
in violation of said copyright.  Writing a book is hard work and unless
the author deliberately wants their book to be given away for free, we
should respect the author's desire to earn a living.

It was also linked it in your reply, which was a violation of your violation.





-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response




Re: Conditional sorting across two arrays

2006-12-12 Thread Mumia W.

On 12/12/2006 04:00 AM, Rinku Mahesh wrote:

  Hi,
   
 I've two arrays of same depth (let it be 6)
   
  1st Array:-  @unique {11 , 23, 44, 66, 900, 1009}

  2nd Array:- @occ_count {2, 77, 22, 2, 77,29}
   
  Here I'm looking for a sorting mechanism with the following conditions:-
   
  a. Sort 2nd Array in descending order such that it should reflect {77,77,29,22,2,2} 
   
  b. The values of 1st array should also change in accordance with the positions of elements of 2nd array such that sorting the 1st array should reflect {23,900,1009,44,11,66}
   
  23 and 900 or 11 and 66 can be interchanged but whatever value is lesser should appear first in the list.
   
  c. As there are repeatations in 2nd Array (77 and 2) there could be two values associated with these elements in 1st array (23/900 or 11/66). Here 23 is lesser than 900 thus it should appear fist in the list.
   
   
  If the above explaination is confusing I'm looking for a way where every element of an array can be mapped to corresponding element of another array and as a whole both the arrays require a sorting w.r.t. 2nd array.
   
   
  Can anyone suggest an eficient way to implement same.
   
  TIA,
   
  Rinku





I hope this is both easy and efficient enough for you:

use strict;
use warnings;
use Sort::Key qw(nkeysort);
my (@unique, @occ_count);
@unique = (66 , 23, 44, 11, 900, 1009);
@occ_count = (2, 77, 22, 2, 77,29);

my @indexes = nkeysort { $occ_count[$_] * 1 + $unique[$_] }
(0..$#occ_count);
@unique = map $unique[$_], @indexes;
@occ_count = map $occ_count[$_], @indexes;
print @unique\n;
print @occ_count\n;



The line where @indexes is assigned is probably the most confusing, so 
I'll only explain that one. Sort::Key allows you to sort while 
specifying your key field in an easy and natural manner. Because I want 
to sort two arrays, I have to sort array indexes--not the arrays 
themselves; that's what (0..$#occ_count) does; it creates a list of 
array indexes.


Inside of the { ... }, I specify the key field on which to sort. The 
easy way to do this would be to use { $occ_count[$_] }, but that would 
only sort the array indexes based on what's in @occ_count, and I have to 
take @unique into consideration also, so I make the occ_count part of 
the forumula much more important than the unique part of the forumla 
by multiplying $occ_count[$_] by 1; this should put it well above 
the range of numbers in @unique.


Then nkeysort tells Sort::Key to do a numeric sort.


HTH



--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/ http://learn.perl.org/first-response