I need to find a way to sort an array of hash references based on the content of one of the hashed items. I know how to do this with a bubble sort, but that is in no way the best answer. If SPLICE can be used to change for example (1 2 3 5 6 4 7 9 8) into (1 2 3 4 5 6 7 9 8) then (1 2 3 4 5 6 7 8 9) by calling SPLICE twice, once each time a non-ordered value is found, I’m sure that would be more efficient.

The last 6 columns of each row will be zero when the data first comes in, and the rows will basically be in random order. The array has to be sorted first by the 3m percentage column and then the ranking 3m column is filled in as shown. In this case, 1 has the highest return for 3 months and 20 has the lowest. The same process is done for each of the other 4 percentage columns and then all of the rankings are added together to create an overall “Rank” and the array is finally sorted by that overall “Rank”.

Now printing the sorted output (hash keys printed in accordance to order of the hash values):

Code

print join "$_\n", sort {$months{$a} <=> $months{$b} } keys %months

This prints:

Code

jan feb mar apr may

If you have a hash ref instead of a hash just change $months{$a} to whatever suits your data structure, for example $months->{$a}, and similarly for $months{$b}. If you have trouble with this, please show your data structure, we will be able to tell you how to sort it.

Re: [PapaGeek] Can SPLICE be used to sort an array of hash references?
[In reply to]

Can't Post

I think this is a fairly complex problem. I used your sample data to come up with a solution. It uses a hash of hashes and a hash of arrays and also introduces something called a hash slice. A hash slice is used when you want to assign to more than one hash element at a time or retrieve more than one hash element at a time. The docs explain some simple hash and array slices http://perldoc.perl.org/perldata.html#Slices]. Click on the menu for 'slices' and it will explain them.

What needs to be done next is the sort the array by each of the “p” (Percentage) values and then define the corresponding “r” (Rank) value so that the highest percentage in each category has a corresponding rank of 1 and in this case of 6 rows, the lowest percentage has a rank of 6. After all the rows are sorted for each of the 5 percentages and the appropriate ranks are defined for each percentage time frame, all 5 of the ranks are added together to give the overall rank of the ticker symbol and the data can be displayed in the order of lowest to highest overall rank.

If these are the ticker symbols that you can invest your 401K money in, you want to be invest in the symbols at the top of the list, not the bottom.

So the question is, how do I sort the list of hash references based on the content of a particular column within each hash.

I’d like to either find the build in sub or write a sub something like: SortHashArray(@hashArray, “p3m”);

Re: [PapaGeek] Can SPLICE be used to sort an array of hash references?
[In reply to]

Can't Post

In Reply To

I’m not sure that I am following you on this one. It looks like you are sorting the hash itself, not an array of hash references.

Yes, I said it was a simple hash, the aim was only to demonstrate the use of the sort function. As I said, the syntax would have to be adapted to your data structure, but I could not really give a detailed solution not knowing what your data structure looked like. Now that you have provided information on the data structure, it is possible to give the exact syntax to sort your data, and Kenosis has supplied the solution to do it.

Re: [Laurent_R] Can SPLICE be used to sort an array of hash references?
[In reply to]

Can't Post

Thank you Laurent,

This is my first real Perl project, I skipped “Hello, World!” Here is a brief description of what I’m working on!

I’m trying to automate the monthly process that I follow to manage my 401K / IRA accounts. I’m taking on a lot of new Perl things, but I’ve got over 45 years of programming experience! I’m using Win32::GUI as my front end, not sure yet what the database will be, and the result will be a few visible GUI pages and a full Intranet website.

I’ve create a DBaccess package to isolate the actual database from the rest of the program. Right now I’m working on a set of real calls to the package that return fake data so I can test the GUI, program logic, and screen scrape software.

The GUI will let you manage lists of accounts, ticker symbols, and current investment amounts. There will be a relation as to what account can invest in what and how much is invested in that account.

The monthly process is to screen scrape the net to update the historical prices on each ticker and calculate the percentage returns over various time frames, 1 week, 3 months, 5 years, etc. After update all of the ticker returns, account by account I read in the ticker data that each account can invest in, create the overall rank as described in this post, and display the information ordered from best return to worse return. The display will also include things like market segment (mid-cap, small-cap, etc) and the amount I currently have invest in that ticker for that account.

The idea is to look at my investment monthly, try to keep the investment in the tickers at or near the top of the list while using the latest week and month returns along with the market segment to help in the decision of what investment if any should be changed. The process does not make any investment decisions, it merely shows you where your money currently is.