Edit: clarification
It's important to note that the goal of JSON API is to be consumed by a general-purpose client (like Ember Data), so the JSON will likely be processed once and indexed as needed. In the system we extracted this from, the Array is loaded into a Store, which indexes the documents by type and id, so future lookups are quite efficient.
In addition, you'll find that you're using an array at the toplevel only for the primary document when it is a collection, and for nested collections within documents (such as comment ids). Semantics that general-purpose clients can make use of.
The original reason for using Arrays (and something that still carries some weight with me), is that people expected that Arrays be presented in a particular order returned by the server. Indeed, the semantics of a to-many relationship need to be set-like (in order to avoid nasty concurrent modification issues), but people really wanted the ability to return an array and have it "work as expected". In general, the right way to handle position, imho, is to use a `position` attribute and sort on the client. After saying all of that, perhaps this is a good reason to use ID indices, so people don't get the wrong idea.
I'll sleep on it :)
For example, consider the posts.comments.users relationship. Here "posts" is the primary document (and let's say a collection), "comments" and "users" are related documents. The same user may have commented in multiple posts within a single response, so which `position` attribute would you use in the related "users" document? The answer is you don't, you can't, because the user appears in different positions in different posts. The order of comments is defined by the "post" document's "comments" array. Each comment document contains a user id. You look up the user from the unique "users" map by that id. There is no order that makes sense for related documents, since by nature of being related documents their entries may appear in different places/positions in the parent document, where they are already referred to from ordered collections (e.g. arrays of ids) or singular fields.
Hope that clears it all up :)
We generate a results array that is ordered based on the default order or supplied order. You can easily iterate over that then do direct lookups in the top level keys.