collection/sortBy.jsjavascript
import { entries, toIteratee } from '../_internal/iteratee'

/**
 * 根据一个或多个 iteratee 对集合进行稳定升序排序。
 * @function sortBy
 * @memberof module:collection
 * @param {Array|Object} collection 要排序的数组或普通对象
 * @param {...(Function|string|number|Array|Object)} iteratees 排序依据
 * @returns {Array} 排序后的新数组,不修改输入集合
 * @throws {TypeError} 集合或 iteratee 类型不正确时抛出
 */
function sortBy(collection, ...iteratees) {
  const fns = (iteratees.length > 0 ? iteratees : [undefined]).map(toIteratee)
  return entries(collection).map(([key, value], index) => ({ key, value, index, criteria: fns.map(fn => fn(value, key, collection)) }))
    .sort((left, right) => {
      for (let index = 0; index < left.criteria.length; index += 1) {
        const a = left.criteria[index]
        const b = right.criteria[index]
        if (Object.is(a, b)) continue
        if (a === undefined || a === null) return 1
        if (b === undefined || b === null) return -1
        if (a < b) return -1
        if (a > b) return 1
      }
      return left.index - right.index
    })
    .map(item => item.value)
}

export default sortBy