code: function sortBy(array, callback, thisArg) {
      if (!array) {
        return [];
      }
      if (typeof callback == 'string') {
        var prop = callback;
        callback = function(array) { return array[prop]; };
      } else if (thisArg) {
        callback = iteratorBind(callback, thisArg);
      }
      var index = -1,
          length = array.length,
          result = Array(length);
  
      while (++index < length) {
        result[index] = {
          'criteria': callback(array[index], index, array),
          'value': array[index]
        };
      }
      result.sort(function(left, right) {
        var a = left.criteria,
            b = right.criteria;
  
        if (a === undefined) {
          return 1;
        }
        if (b === undefined) {
          return -1;
        }
        return a < b ? -1 : a > b ? 1 : 0;
      });
  
      while (length--) {
        result[length] = result[length].value;
      }
      return result;
    }
docs: Produces a new sorted array, ranked in ascending order by the results of
  running each element of `array` through `callback`. The `callback` is
  bound to `thisArg` and invoked with 3 arguments; (value, index, array). The
  `callback` argument may also be the name of a property to sort by (e.g. 'length').
  
  @static
  @memberOf _
  @category Arrays
  @param {Array} array The array to iterate over.
  @param {Function|String} callback The function called per iteration or
  property name to sort by.
  @param {Mixed} [thisArg] The `this` binding for the callback.
  @returns {Array} Returns a new array of sorted values.
  @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]
  
  _.sortBy(['larry', 'brendan', 'moe'], 'length');
  // => ['moe', 'larry', 'brendan']