function sortBy(collection, callback, thisArg) {
      var index = -1,
          isArr = isArray(callback),
          length = collection ? collection.length : 0,
          result = Array(typeof length == 'number' ? length : 0);

      if (!isArr) {
        callback = lodash.createCallback(callback, thisArg, 3);
      }
      forEach(collection, function(value, key, collection) {
        var object = result[++index] = getObject();
        if (isArr) {
          object.criteria = map(callback, function(key) { return value[key]; });
        } else {
          (object.criteria = getArray())[0] = callback(value, key, collection);
        }
        object.index = index;
        object.value = value;
      });

      length = result.length;
      result.sort(compareAscending);
      while (length--) {
        var object = result[length];
        result[length] = object.value;
        if (!isArr) {
          releaseArray(object.criteria);
        }
        releaseObject(object);
      }
      return result;
    }
Creates an array of elements, sorted in ascending order by the results of
running each element in a collection through the callback. This method
performs a stable sort, that is, it will preserve the original sort order
of equal elements. The callback is bound to `thisArg` and invoked with
three arguments; (value, index|key, collection).

If a property name is provided for `callback` the created "_.pluck" style
callback will return the property value of the given element.

If an array of property names is provided for `callback` the collection
will be sorted by each property value.

If an object is provided for `callback` the created "_.where" style callback
will return `true` for elements that have the properties of the given object,
else `false`.

@static
@memberOf _
@category Collections
@param {Array|Object|string} collection The collection to iterate over.
@param {Array|Function|Object|string} [callback=identity] The function called
 per iteration. If a property name or object is provided it will be used
 to create a "_.pluck" or "_.where" style callback, respectively.
@param {*} [thisArg] The `this` binding of `callback`.
@returns {Array} Returns a new array of sorted elements.
@example

_.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
// => [3, 1, 2]

_.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
// => [3, 1, 2]

var characters = [
  { 'name': 'barney',  'age': 36 },
  { 'name': 'fred',    'age': 40 },
  { 'name': 'barney',  'age': 26 },
  { 'name': 'fred',    'age': 30 }
];

// using "_.pluck" callback shorthand
_.map(_.sortBy(characters, 'age'), _.values);
// => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]]

// sorting by multiple properties
_.map(_.sortBy(characters, ['name', 'age']), _.values);
// = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]]