// // generic comparator implementations our types can use // var collation = exports // // scalar comparisons // collation.inequality = function (a, b) { return a < b ? -1 : ( a > b ? 1 : 0 ) } collation.difference = function (a, b) { return a - b } // // recursive collations have to be provided a collation function to delegate to // collation.recursive = {} // // element by element (comparison for list-like structures // collation.recursive.elementwise = function (compare, shortlex) { return function (a, b) { var aLength = a.length var bLength = b.length var difference // // short-circuit on length difference for shortlex semantics // if (shortlex && aLength !== bLength) return aLength - bLength for (var i = 0, length = Math.min(aLength, bLength); i < length; ++i) { if (difference = compare(a[i], b[i])) return difference } return aLength - bLength } } // // field by field comparison of record-like structures // collation.recursive.fieldwise = function (compare, shortlex) { return function (a, b) { var aKeys = Object.keys(a) var bKeys = Object.keys(b) var aLength = aKeys.length var bLength = bKeys.length var difference // // short-circuit on length difference for shortlex semantics // if (shortlex && aLength !== bLength) return aLength - bLength for (var i = 0, length = Math.min(aLength, bLength); i < length; ++i) { // // first compare keys // if (difference = compare(aKeys[i], bKeys[i])) return difference // // then compare values // if (difference = compare(a[aKeys[i]], b[bKeys[i]])) return difference } return aLength - bLength } } // // elementwise compare with inequality can be used for binary equality // collation.bitwise = collation.recursive.elementwise(exports.inequality)