73207

Sorting a multi-dimensional array in JavaScript using a custom sort function

Sorting multi-dimensional array in JavaScript. Perused other posts, but can't figure out how to pass the array members to the custom sort function, which determines whether to sort a string or numbers. Custom sort function is this:

function colSort(a, b) { if (sortDown) dValue = 1 else dValue = -1; if (isNumeric(a[sortIndex])) { return (b[sortIndex] - a[sortIndex]) * dValue; } else { var astring = a[sortIndex].toLowerCase(); var bstring = b[sortIndex].toLowerCase(); if (bstring > astring) return -dValue; if (bstring < astring) return dValue; return 0; } }

Array looks like this:

var qbStats =[ ['David Lea', 'GB', 343, 502, 68.3, 4643, 9.2, 45, 6, 122.5], ['Kevin Whyte', 'NO', 440, 622, 70.7, 5087, 8.2, 41, 13, 108.4] ]

The column headers in a HTML table listing array members should be able to be clicked to sort ascending/descending on the clicked column.

I can't figure out how to indicate members to be sorted on the clicked index.

I know it starts as:

qbStats.sort(colSort(a,b));

But I don't know how to pass the array members to be sorted on the specific index. Ex: How do I tell it to sort on 'GB' and 'NO' as 'a' and 'b'? Thanks for any help you can give!

Answer1:

The comparison callback to the sort() function is called by the sorting process and passed pairs of array elements. You don't have to tell anything which elements to compare; the sorting process already knows that.

In your case, the issue is that you essentially need a sort function per column. You can handle that by creating a function that returns another function, one that "knows" which column to compare:

function byColumn(sortIndex) { return function colSort(a, b) { if (sortDown) dValue = 1 else dValue = -1; if (isNumeric(a[sortIndex])) { return (b[sortIndex] - a[sortIndex]) * dValue; } else { var astring = a[sortIndex].toLowerCase(); var bstring = b[sortIndex].toLowerCase(); if (bstring > astring) return -dValue; if (bstring < astring) return dValue; return 0; } }; }

And then:

qbStats.sort(byColumn(4)); // sort by column 4

The byColumn() function is just a simple wrapper around your comparator function. When it is called, it returns the actual function that the sort process will use. That function has access to the sortIndex parameter that was passed in at its creation time, so it intrinsically "knows" how to compare two rows.

Answer2:

Maybe this is something for you. The function returns for any case the right function to compare.

<div class="snippet" data-lang="js" data-hide="false"> <div class="snippet-code">

var qbStats = [['David Lea', 'GB', 343, 502, 68.3, 4643, 9.2, 45, 6, 122.5], ['Kevin Whyte', 'NO', 440, 622, 70.7, 5087, 8.2, 41, 13, 108.4]];

function sort(column, sortOrder, isNumber) {
    if (isNumber) {
        if (~sortOrder) {
            return function (a, b) {
                return a[column] - b[column];
            }
        } else {
            return function (a, b) {
                return b[column] - a[column];
            }
        }
    } else {
        if (~sortOrder) {
            return function (a, b) {
                return a[column].localeCompare(b[column]);
            }
        } else {
            return function (a, b) {
                return b[column].localeCompare(a[column]);
            }
        }
    }
}

qbStats.sort(sort(0, 1, false)); // sort 0th column, ascending by string
document.write('<pre>' + JSON.stringify(qbStats, 0, 4) + '</pre>');

qbStats.sort(sort(2, -1, true)); // sort 2th column, descending by number
document.write('<pre>' + JSON.stringify(qbStats, 0, 4) + '</pre>');


Recommend

  • C++ I'm stuck filling this BST with its proper values
  • How can I get the values I set for custom properties in AddressBook to persist?
  • More elegant way to group DataTable data in structs in C# (using Linq?)
  • Making cut/replace methods with JTextArea
  • x86 lea instruction
  • Java 7 ForkJoinTask and Akka 2.0
  • Add up all elements of compile-time sized array most efficiently
  • JavaScript RegEx to match punctuation NOT part of any HTML tags
  • What does 0x0 indicate in the instruction
  • Can i run WebAppContext with WebSocketHandler in same instance?
  • Does Accurev support stashing?
  • Increasing dimensions on hover without changing the position of other elements
  • Javascript and VERY LONG string
  • How to do custom filtering in Datatables with comma separated values?
  • PE file - what's missing?
  • how to swap Image in jquery
  • @Autowired for @ModelAttribute
  • ConnectivityManager.CONNECTIVITY_ACTION deprecated
  • Memory error in python- how to use more memory
  • Optimizing database types to compact database (SQLite)
  • Rearranging Cells in UITableView Bug & Saving Changes
  • How to delete a row from a dynamic generate table using jquery?
  • Benchmarking RAM performance - UWP and C#
  • using HTMLImports.whenReady not working in chrome
  • Angular 2 constructor injection vs direct access
  • Change div Background jquery
  • How to get Windows thread pool to call class member function?
  • IndexOutOfRangeException on multidimensional array despite using GetLength check
  • Authorize attributes not working in MVC 4
  • Bitwise OR returns boolean when one of operands is nil
  • EntityFramework adding new object to nested object collection
  • XCode 8, some methods disappeared ? ex: layoutAttributesClass() -> AnyClass
  • Easiest way to encapsulate a HTML5 webpage into an android app?
  • Busy indicator not showing up in wpf window [duplicate]
  • costura.fody for a dll that references another dll
  • Observable and ngFor in Angular 2
  • How to Embed XSL into XML
  • UserPrincipal.Current returns apppool on IIS
  • Conditional In-Line CSS for IE and Others?
  • java string with new operator and a literal