Skip to content

Order from chaos

This part will cover

  • Sorting / grade up / grade down
  • Windowed reduce

As a moviegoer, you love to share the movies you've watched with friends and family. It would be ideal if they could watch all of them, but since your friends have busy schedules you'd like to prioritize your most favorite ones. In order to do this, you need to first sort your movies by rating.

Luckily, APL implements functions that help sort a list, but they're a little different from other languages. Instead of returning a sorted list, grade up and grade down return the indices of the elements of the final sorted array in the initial unsorted array.

Given your array of movies, you get the array of ratings and use the grade down function.

MovieDB  [ 'Title' 'Year' 'Rating' 'Runtime' 'Watches' 'Genre' 
            'Real Genius' 1985 4 108 3 'Comedy'  
            'Eraserhead' 1977 3.5 89 1 'Fantasy' 
            'The Devil Wears Prada' 2006 4.5 109 2 'Comedy' 
            '12 Angry Men' 1957 5 96 4 'Thriller'
            ]
       MovieDB
┌─────────────────────┬────┬──────┬───────┬───────┬────────┐
Title                YearRatingRuntimeWatchesGenre   
├─────────────────────┼────┼──────┼───────┼───────┼────────┤
Real Genius          19854     108    3      Comedy  
├─────────────────────┼────┼──────┼───────┼───────┼────────┤
Eraserhead           19773.5   89     1      Fantasy 
├─────────────────────┼────┼──────┼───────┼───────┼────────┤
The Devil Wears Prada20064.5   109    2      Comedy  
├─────────────────────┼────┼──────┼───────┼───────┼────────┤
12 Angry Men         19575     96     4      Thriller
└─────────────────────┴────┴──────┴───────┴───────┴────────┘
      1MovieDB[;3]
4 3.5 4.5 5
      1MovieDB[;3]
4 3 1 2

This result tells us that the first element of the sorted array is the 4th element of the ratings array, the second is the 3rd, and so on. We can obtain the sorted array by accessing these indices.

       (1MovieDB[;3])[1MovieDB[;3]]
5 4.5 4 3.5

The result is as expected. Since the array obtained from grade down is in terms of indices, then we can also use it to access the movie title and movie runtime arrays.

       (1MovieDB[;1])
┌───────────┬──────────┬─────────────────────┬────────────┐
Real GeniusEraserheadThe Devil Wears Prada12 Angry Men
└───────────┴──────────┴─────────────────────┴────────────┘
       (1MovieDB[;1])[1MovieDB[;3]]
┌────────────┬─────────────────────┬───────────┬──────────┐
12 Angry MenThe Devil Wears PradaReal GeniusEraserhead
└────────────┴─────────────────────┴───────────┴──────────┘

As expected! Then, you find the cumulative watch time of the sorted array.

       +\(1MovieDB[;4])[1MovieDB[;3]]
96 205 313 402

You think roughly three hours is a reasonable amount of time to get people together for, but then you realise the tone of the movies would be all over the place! You realise you'd like movies of the same genre instead.

First, you sort by genre.

       (1MovieDB[;6])[1MovieDB[;6]]
┌────────┬───────┬──────┬──────┐
ThrillerFantasyComedyComedy
└────────┴───────┴──────┴──────┘
       (1MovieDB[;1])[1MovieDB[;6]]
┌────────────┬──────────┬───────────┬─────────────────────┐
12 Angry MenEraserheadReal GeniusThe Devil Wears Prada
└────────────┴──────────┴───────────┴─────────────────────┘

Then, you'd like to compare the genre of each successive pair of movies, this is where a special kind of reduction called windowed reduction can be used. In addition to reducing a whole vector, you can also reduce successive chunks of a vector by specifying an integer left argument.

For a simple array ⎕A of the alphabet, the result of reducing along catenate with chunks of length 2, 2,/, is pairs of successive letters.

       2,/⎕A
┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
ABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZ
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘

For our list of genres, we'd like to check for equality, then access the first index with a matching genre. We will use the indices of function, which returns the indices of 1s, more on searching in Part 5.

       sorted_genres(1MovieDB[;6])[1MovieDB[;6]]
┌────────┬───────┬──────┬──────┐
ThrillerFantasyComedyComedy
└────────┴───────┴──────┴──────┘
       2/sorted_genres
0 0 1
       2/sorted_genres
3
       (sorted_genres)[2/sorted_genres]
┌──────┐
Comedy
└──────┘

Comedy it is!