_.flatMap(collection, [iteratee=_.identity])
72
_.flatMap(collection, [iteratee=_.identity])
_.flatMap先map遍历集合的所有元素调用iteratee后再将其展平,返回新的展平的数组,只展开一层
参数
collection (Array|Object): 需要遍历展开的集合
[iteratee=_.identity] (Function): 遍历时每个元素调用的方法
返回值
(Array): 返回新的展开的数组
例子
function duplicate(n) { return [n, n]; } _.flatMap([1, 2], duplicate); // => [1, 1, 2, 2]
源代码:
import baseFlatten from './.internal/baseFlatten.js' import map from './map.js' /** * Creates a flattened array of values by running each element in `collection` * thru `iteratee` and flattening the mapped results. The iteratee is invoked * with three arguments: (value, index|key, collection). * * @since 4.0.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the new flattened array. * @see flatMapDeep, flatMapDepth, flatten, flattenDeep, flattenDepth, map, mapKeys, mapValues * @example * * function duplicate(n) { * return [n, n] * } * * flatMap([1, 2], duplicate) * // => [1, 1, 2, 2] */ //先map遍历集合的所有元素调用iteratee后再将其展平,返回新的展平的数组 //只展开一层 function flatMap(collection, iteratee) { return baseFlatten(map(collection, iteratee), 1) } export default flatMap
map
/** * Creates an array of values by running each element of `array` thru `iteratee`. * The iteratee is invoked with three arguments: (value, index, array). * * @since 5.0.0 * @category Array * @param {Array} array The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the new mapped array. * @example * * function square(n) { * return n * n * } * * map([4, 8], square) * // => [16, 64] */ //对数组每一个元素执行迭代器后返回由返回值组成的新数组 function map(array, iteratee) { let index = -1//循环索引 const length = array == null ? 0 : array.length//数组长度 const result = new Array(length)//结果数组 while (++index < length) {//循环调用迭代器,把处理后的返回值存入结果数组 result[index] = iteratee(array[index], index, array) } return result } export default map
baseFlatten
import isFlattenable from './isFlattenable.js' /** * The base implementation of `flatten` with support for restricting flattening. * * @private * @param {Array} array The array to flatten. * @param {number} depth The maximum recursion depth. * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. * @param {Array} [result=[]] The initial result value. * @returns {Array} Returns the new flattened array. */ //这个方法用于数组展开 //array需要展开操作的数组,depth需要展开的层数 //predicate用于判断值是否可展开 //isStrict标识用于判断是否约束值必须通过predicate方法的检查 function baseFlatten(array, depth, predicate, isStrict, result) { predicate || (predicate = isFlattenable)//predicate每次循环都会调用,用来判断当前值是否是一个可展开的array-like对象 result || (result = []) if (array == null) {//需要展开的数组是空,就返回空数组 return result } for (const value of array) { if (depth > 0 && predicate(value)) {//如果展开层数大于0且当前循环值可展开 if (depth > 1) {//如果展开层数大于一层就继续递归调用,层数减一 // Recursively flatten arrays (susceptible to call stack limits). baseFlatten(value, depth - 1, predicate, isStrict, result) } else {//如果只展开一层,就展开后push到result里 result.push(...value) } } else if (!isStrict) {//如果没有传递isStrict标识,就直接将当前循环值push入结果数组 result[result.length] = value } } return result } export default baseFlatten
isFlattenable
import isArguments from '../isArguments.js' /** Built-in value reference. */ const spreadableSymbol = Symbol.isConcatSpreadable /** * Checks if `value` is a flattenable `arguments` object or array. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. */ //检查一个变量是否是一个可展开的对象或者数组 function isFlattenable(value) { return Array.isArray(value) || isArguments(value) || !!(spreadableSymbol && value && value[spreadableSymbol]) //如果是数组,则可展开 //如果是arguments对象,则可展开 //如果当前环境含有Symbol对象,且此变量含有Symbol.isConcatSpreadable属性,Symbol.isConcatSpreadable用于改变array或者array-like对象使用concat时的默认行为 } export default isFlattenable