Batman.js is no longer in production at Shopify and is not actively maintained.

This website is left for reference (and for old times' sake).


Batman.SetSort is a Batman.SetProxy which sorts the members of its base by provided key and order. Through SetProxy, SetSort extends Batman.Object and Batman.Enumerable. SetSorts are generally derived from Sets. For example:

test "SetSorts are sorted proxies of their Sets", ->
  batmobile = new Batman.Object(name: "Batmobile", wheelCount: 4)
  batcycle = new Batman.Object(name: "Batcycle", wheelCount: 2)
  vehicles = new Batman.Set(batmobile, batcycle)

  vehiclesByWheelCount1 = new Batman.SetSort(vehicles, 'wheelCount') # order defaults to 'asc'
  vehiclesByWheelCount2 = vehicles.sortedBy('wheelCount')
  vehiclesByWheelCount3 = vehicles.get('sortedBy.wheelCount')

  batcopter = new Batman.Object(name: "Batcopter", wheelCount: 0)

  for setSort in [vehiclesByWheelCount1, vehiclesByWheelCount2, vehiclesByWheelCount3]
    deepEqual setSort.mapToProperty('wheelCount'), [0, 2, 4]

Using a Batman.SetSort

Batman.SetSort is batman.js's ordered collection data structure. Batman.Set does not have a specific order, but a Batman.SetSort does.

Since a SetSort is a proxy of a Set, the easiest way to make one is to use Set::sortedBy:

sortedVehicles = vehicles.sortedBy('wheelcount')

You can also make SetSorts in view bindings:

  <li data-foreach-vehicle='vehicles.sortedBy.wheelcount'>
    <!-- will render vehicles ordered by wheelcount -->

SetSorts are observable proxies of their underlying Sets. So, when the Set is changed (ie, items are added, removed, or modified):

  • The SetSort is automatically updated by batman.js
  • Any view bindings or accessors depending on the SetSort are updated
  • constructor(base : Set, key : String, order : ["asc"|"desc", default "asc"]) : SetSort

    Returns a new SetSort, tracking base and ordering by key in the direction of order.

  • isSorted[= true]

    Returns true.

  • key : String

    Returns the key used to sort members of the SetSort, as defined in the constructor.

  • descending

    true if "desc" was passed to as order to the constructor, otherwise false. Descending SetSorts may also be made by getting sortedByDescending from a Set:

    test "get sortedByDescending creates a descending SetSort", ->
      batmobile = new Batman.Object(name: "Batmobile", wheelCount: 4)
      batcycle = new Batman.Object(name: "Batcycle", wheelCount: 2)
      vehicles = new Batman.Set(batmobile, batcycle)
      vehiclesByWheelCountDescending1 = new Batman.SetSort(vehicles, 'wheelCount', 'desc')
      vehiclesByWheelCountDescending2 = vehicles.get('sortedByDescending.wheelCount')
      for descendingSetSort in [vehiclesByWheelCountDescending1, vehiclesByWheelCountDescending2]
        equal descendingSetSort.descending, true
        deepEqual descendingSetSort.mapToProperty('wheelCount'), [4, 2]
  • find(func : Function)

    Returns the first item from the SetSort for which func(item) returns a truthy value.

  • forEach(func : Function)

    Calls func(item) for each item in the SetSort.

  • toArray() : Array

    Returns a sorted array representation of the SetSort's contents.

  • merge(other : Set) : SetSort

    Returns a new SetSort whose items are the union of this SetSort and other. It will have the same key and order as the starting SetSort.

  • compare(a, b) : Number


    • -1 if a has higher precedence than b
    • 0 if a and b have equal precedence or if precedence can't be determined
    • 1 if b has higher precedence than a

    Precedence is determined by testing for undefined, null, false, true, NaN, a < b and a > b. Please see the source for implementation details.

    Since ::compareElements delegates to ::compare, you can acheive custom sorting by overriding ::compare in a SetSort subclass.

  • compareElements(a, b) : Number

    Used by SetSort to compare its elements when sorting. Like ::compare, it returns -1, 0, or 1. To arrive at this value, it:

    • tries a.get(@key) (where @key is the SetSorts key)
    • if the resulting value is a function, calls resultingFunction(a)
    • calls resultingValue.valueOf()
    • repeats the process for b
    • delegates to ::compare to compare the resulting values
    • inverts the value if ::.descending

    By following this process, it provides sort values for Batman.Objects a and b according to @key.

Help us improve our documentation!

Contributions to this page are welcome on Github. If you find a problem but you cannot fix it, please open an issue.

Discussion regarding batman.js documentation is also welcome on our mailing list.