Re: Conditional sorting across two arrays
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
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
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
--- 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
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
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
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