0

When compiling a bibliographic list, you often need to sort at multiple levels. e.g. if same author and same publication year, then sort by title (etc.). In SQL this is easy enough. However, I need to do it in javascript. I have some javascript code (a Word add-in) that pulls in bibliographic data from several databases (on separate servers) via XmlHTTP and then compiles a complete bibliographic list which should be sorted according to the three hierarchical levels above. e.g., if I have the following raw data back from multiple SQL servers:

  • a_author, 2000, a_title
  • c_author, 2011, b_title
  • b_author, 1899, c_title
  • a_author, 2000, d_title
  • a_author, 1999, e_title

then, sorting heirarchically according to ascending author, ascending year, ascending title, I should get:

  • a_author, 1999, e_title
  • a_author, 2000, a_title
  • a_author, 2000, d_title
  • b_author, 1899, c_title
  • c_author, 2011, b_title

Note that author and title fields are string sorts while year is a numerical sort.

I know how to use a cmp function on any of those fields but only on one field at a time. In this, my strategy has been to create an ordinary array of formatted bibliographic entries from the various SQL databases alongside an array of objects that match the bibliographic array's (automatically generated) index. Thus (if ordering by author only):

        if (!finalizeReferences.includes(xmlResponse[j].bibEntry)) {
          finalizeReferences.push(xmlResponse[j].bibEntry);
          key = finalizeReferences.indexOf(xmlResponse[j].bibEntry);
          multipleOrder.push([key, xmlResponse[j].authorOrder]);
        }

      var bibliography = '';
      var key;
      multipleOrder.sort(function (a, b){return a[1].localeCompare(b[1])});
      if (ascDesc == 'DESC') { // Descending order?
        multipleOrder.reverse();
      }
      for (i = 0; i < multipleOrder.length; i++) {
        key = multipleOrder[i][0];
        bibliography += '<p>' + finalizeReferences[key] + '</p>';
      }

As an example, finalReferences might be:

["a_author (2000). a_title. Oxford: OUP.", "a_author (2000). d_title. Cambridge: CUP.", "b_author (1899). c_title. Cambridge (MA): MIT.", (etc.)]

and multipleOrder would be:

[[0, a_author], [1, a_author], [2, b_author], (etc.)] (where the numbers refer to the indices of finalReferences).

The comparison function of multipleOrder.sort, then sorts on the author field (reversing the multipleOrder object if required), then multipleOrder is looped, pulling out the appropriate full bibliographic entry in the right order.

Now . . . if I had the following three arrays of objects:

multipleOrderAuthor = [[0, a_author], [1, a_author], [2, b_author], (etc.)]

multipleOrderYear = [[0, 2000], [1, 2000], [2, 1899], (etc.)]

multipleOrderTitle = [[0, a_title], [1, d_title], [2, c_title], (etc.)]

how would I amend my second snippet of code above so that I can pull out the bibliographic entries ordered by author then year then title (or year then author then title etc.)?

  • See the answers to the [linked question](https://stackoverflow.com/questions/6913512/). Basically, you compare your most major field (`author` I think, e.g. `result = a.author.localeCompare(b.author)` and if the result is not `0`, return that from your `sort` callback; if the result of the most major field comparison is `0` check your next most major field (`year` I think, so `result = a.year - b.year`) and, again, if that result is not `0` return it; otherwise continue with your next criterion, and so on. Return the result of your final comparison regardless of what it is. – T.J. Crowder Feb 16 '21 at 10:59
  • Great link – thank you. It fit the bill perfectly. Apologies for duplicating – finding the right terminology/words for searching here and pulling up previous answers is a difficult art. – Mark Grimshaw-Aagaard Feb 16 '21 at 11:22
  • Duplicates aren't necessarily a bad thing! Now if someone searches using the terms you used, they'll find your question, and through it the earlier one. :-) Happy coding! – T.J. Crowder Feb 16 '21 at 11:25

0 Answers0