Sorting by Size

Currently this program prints the file and directory names and their sizes in alphabetical order. But I am more interested in their relative sizes. It would, therefore, be more useful if the files were sorted by size rather than by name.

To be able to sort the files, you need some way of storing a complete list of all file sizes. One obvious way of doing this would be to add the file sizes to an array. In file_info2.rb, I create an empty array, $files, and each time a file is processed, I append its size to the array:

file_info2.rb

$files << fsize

I can then sort the file sizes to display low to high values or (by sorting and then reversing the array) to display from high to low values:

$files.sort                   # sort low to high
$files.sort.reverse           # sort high to low

The only trouble with this is that I now end up with an array of file sizes without the associated filenames. A better solution would be to use a Hash instead of an Array. I’ve done this in file_info3.rb. First, I create two empty Hashes:

file_info3.rb

$dirs = {}
$files = {}

Now, when the processfiles method encounters a directory, it adds a new entry to the $dirs Hash using the full directory path, mypath, as the key and using the directory size, dsize, as the value:

$dirs[mypath] = dsize

Key-value pairs are similarly added to the $files hash. When the entire structure of subdirectories and files has been processed by recursive calls to the processfiles method, the $dirs hash variable will contain key-value pairs of directory names and sizes, and the $files hash will contain key-value pairs of file names and sizes.

All that remains now is for these hashes to be sorted and displayed. The standard sort method for a Hash sorts the keys, not the values. I want to sort the values (sizes), not the keys (names). To do this, I have defined a custom sort method (refer to Chapter 4 and Chapter 5 for guidance on defining custom comparisons using <=>):

$files.sort{|a,b| a[1]<=>b[1]}

Here the sort method converts the $files Hash into nested arrays of [key,value] pairs and passes two of these, a and b, into the block between curly brackets. The second item (at index [1]) of each [key,value] pair provides the value. The sorting itself is done on the value using Ruby’s <=> comparison method. The end result is that this program now displays first a list of files in ascending order (by size) and then a similarly sorted list of directories. This is an example of its output:

..ch19logappmodelspost.rb : 36 bytes
..ch19say_hello.html.erb : 41 bytes
..ch13	estfile.txt : 57 bytes
..ch012helloname.rb : 67 bytes
..ch9div_by_zero.rb : 71 bytes
..ch12	est.rb : 79 bytes
..ch4dir_array.rb : 81 bytes
..ch3for_to.rb : 89 bytes
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.31.22