_.keyBy(collection, [iteratee=_.identity])


80

_.keyBy(collection, [iteratee=_.identity])

_.keyBy创建一个对象,这个对象的key生成自collection的每一个元素调用iteratee的结果,每一个key对应的value是最后一个负责生成对应key的collection的元素

参数

collection (Array|Object): 需要遍历的集合
[iteratee=_.identity] (Function): 生成结果数组的key的方法

返回值

(Object): 返回累加好的对象

例子

var array = [
  { 'dir': 'left', 'code': 97 },
  { 'dir': 'right', 'code': 100 }
];
 
_.keyBy(array, function(o) {
  return String.fromCharCode(o.code);
});
// => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
 
_.keyBy(array, 'dir');
// => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }

源代码:

import baseAssignValue from './.internal/baseAssignValue.js'
import reduce from './reduce.js'

/**
 * Creates an object composed of keys generated from the results of running
 * each element of `collection` thru `iteratee`. The corresponding value of
 * each key is the last element responsible for generating the key. The
 * iteratee is invoked with one argument: (value).
 *
 * @since 4.0.0
 * @category Collection
 * @param {Array|Object} collection The collection to iterate over.
 * @param {Function} iteratee The iteratee to transform keys.
 * @returns {Object} Returns the composed aggregate object.
 * @see groupBy, partition
 * @example
 *
 * const array = [
 *   { 'dir': 'left', 'code': 97 },
 *   { 'dir': 'right', 'code': 100 }
 * ]
 *
 * keyBy(array, ({ code }) => String.fromCharCode(code))
 * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
 */
//创建一个对象,这个对象的key生成自collection的每一个元素调用iteratee的结果,每一个key对应的value是最后一个负责生成对应key的collection的元素
function keyBy(collection, iteratee) {
  return reduce(collection, (result, value, key) => (
    //调用reduce方法,遍历collection,往累加对象result上累加元素
    //key是iteratee的返回值,value是collection当前value
    baseAssignValue(result, iteratee(value), value), result
  ), {})
}

export default keyBy
baseAssignValue
/**
 * The base implementation of `assignValue` and `assignMergeValue` without
 * value checks.
 *
 * @private
 * @param {Object} object The object to modify.
 * @param {string} key The key of the property to assign.
 * @param {*} value The value to assign.
 */
//assignValue和assignMergeValue的基础实现
function baseAssignValue(object, key, value) {
  if (key == '__proto__') {//如果key是__proto__,就用Object.defineProperty设置
    Object.defineProperty(object, key, {
      'configurable': true,
      'enumerable': true,
      'value': value,
      'writable': true
    })
  } else {//否则直接设置
    object[key] = value
  }
}

export default baseAssignValue
reduce
import arrayReduce from './.internal/arrayReduce.js'
import baseEach from './.internal/baseEach.js'
import baseReduce from './.internal/baseReduce.js'

/**
 * Reduces `collection` to a value which is the accumulated result of running
 * each element in `collection` thru `iteratee`, where each successive
 * invocation is supplied the return value of the previous. If `accumulator`
 * is not given, the first element of `collection` is used as the initial
 * value. The iteratee is invoked with four arguments:
 * (accumulator, value, index|key, collection).
 *
 * Many lodash methods are guarded to work as iteratees for methods like
 * `reduce`, `reduceRight`, and `transform`.
 *
 * The guarded methods are:
 * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
 * and `sortBy`
 *
 * @since 0.1.0
 * @category Collection
 * @param {Array|Object} collection The collection to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @param {*} [accumulator] The initial value.
 * @returns {*} Returns the accumulated value.
 * @see reduceRight, transform
 * @example
 *
 * reduce([1, 2], (sum, n) => sum + n, 0)
 * // => 3
 *
 * reduce({ 'a': 1, 'b': 2, 'c': 1 }, (result, value, key) => {
 *   (result[value] || (result[value] = [])).push(key)
 *   return result
 * }, {})
 * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
 */
//将每一个集合中的元素通过iteratee处理后的结果累加到一个值,每一次连续的调用的累加值都是上一次的返回值。如果初始累加值没有提供,就使用第一次循环的返回值
function reduce(collection, iteratee, accumulator) {
  const func = Array.isArray(collection) ? arrayReduce : baseReduce//判断collection参数是数组还是其他类型,如果是数组调用arrayReduce,否则baseReduce
  const initAccum = arguments.length < 3
  return func(collection, iteratee, accumulator, initAccum, baseEach)
}

export default reduce
arrayReduce
/**
 * A specialized version of `reduce` for arrays.
 *
 * @private
 * @param {Array} [array] The array to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @param {*} [accumulator] The initial value.
 * @param {boolean} [initAccum] Specify using the first element of `array` as
 *  the initial value.
 * @returns {*} Returns the accumulated value.
 */
//为数组类型数据提供的reduce方法
function arrayReduce(array, iteratee, accumulator, initAccum) {
  let index = -1//循环索引
  const length = array == null ? 0 : array.length//数组长度

  if (initAccum && length) {//如果没有提供累加器初始值,且数组至少有一个元素,累加器初始值就是数组第一个元素
    accumulator = array[++index]
  }
  while (++index < length) {//循环累加
    accumulator = iteratee(accumulator, array[index], index, array)
  }
  return accumulator
}

export default arrayReduce

baseReduce

/**
 * The base implementation of `reduce` and `reduceRight` which iterates
 * over `collection` using `eachFunc`.
 *
 * @private
 * @param {Array|Object} collection The collection to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @param {*} accumulator The initial value.
 * @param {boolean} initAccum Specify using the first or last element of
 *  `collection` as the initial value.
 * @param {Function} eachFunc The function to iterate over `collection`.
 * @returns {*} Returns the accumulated value.
 */
//reduce基础实现,使用eachFunc方法执行累加的方法
function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
  eachFunc(collection, (value, index, collection) => {
    accumulator = initAccum
      ? (initAccum = false, value)
      : iteratee(accumulator, value, index, collection)
      //如果没有提供累加初始值,就用第一个元素作为初始值
  })
  return accumulator
}

export default baseReduce
baseEach
import baseForOwn from './baseForOwn.js'
import isArrayLike from '../isArrayLike.js'

/**
 * The base implementation of `forEach`.
 *
 * @private
 * @param {Array|Object} collection The collection to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Array|Object} Returns `collection`.
 */
//forEach的基础实现
//collection被迭代遍历的对象,iteratee遍历器
function baseEach(collection, iteratee) {
  if (collection == null) {//如果collection为空,直接返回原对象
    return collection
  }
  if (!isArrayLike(collection)) {//如果collection不是array-like对象,就调用baseForOwn处理
    return baseForOwn(collection, iteratee)
  }
  const length = collection.length//对象长度
  const iterable = Object(collection)
  let index = -1//循环索引

  while (++index < length) {//循环调用iteratee方法,如果iteratee返回值是false,提前跳出循环结束
    if (iteratee(iterable[index], index, iterable) === false) {
      break
    }
  }
  return collection
}

export default baseEach
baseForOwn
import baseFor from './baseFor.js'
import keys from '../keys.js'

/**
 * The base implementation of `forOwn`.
 *
 * @private
 * @param {Object} object The object to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Object} Returns `object`.
 */
//forOwn方法的基础实现
function baseForOwn(object, iteratee) {
  return object && baseFor(object, iteratee, keys)//如果object不为空,调用baseFor处理
}

export default baseForOwn
baseFor
/**
 * The base implementation of `baseForOwn` which iterates over `object`
 * properties returned by `keysFunc` and invokes `iteratee` for each property.
 * Iteratee functions may exit iteration early by explicitly returning `false`.
 *
 * @private
 * @param {Object} object The object to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @param {Function} keysFunc The function to get the keys of `object`.
 * @returns {Object} Returns `object`.
 */
//baseForOwn的基础实现,通过keysFunc遍历对象每一个属性,用iteratee处理每个属性值
//iteratee可以返回false跳出循环
function baseFor(object, iteratee, keysFunc) {
  const iterable = Object(object)
  const props = keysFunc(object)//key组成的数组
  let { length } = props//key数组长度
  let index = -1//循环索引

  while (length--) {//遍历key数组
    const key = props[++index]//当前key
    if (iteratee(iterable[key], key, iterable) === false) {//调用iteratee
      break
    }
  }
  return object
}

export default baseFor

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM