zoukankan      html  css  js  c++  java
  • lodash源码学习(13)

    继续学习lodash,math部分,也就是一些数学相关的方法

    “Math” Methods

    _.add(augend, addend)

    加法函数.
    //add.js
    var createMathOperation = require('./_createMathOperation'); //包装方法
    
    /**
     * 
     *
     * @param {number} augend 相加的第一个值.
     * @param {number} addend 相加的第二个值.
     * @returns {number} 返回总值.
     * @example
     *
     * _.add(6, 4);
     * // => 10
     */
    var add = createMathOperation(function(augend, addend) {// 调用createMathOperation
      return augend + addend;
    }, 0);
    
    module.exports = add;

    依赖于包装方法createMathOperation

    //.createMathOperation.js
    
    var baseToNumber = require('./_baseToNumber'), //转化为数字
        baseToString = require('./_baseToString'); //转化为字符串
    
    /**
     * 闯将一个方法对两个值进行数学操作.
     *
     * @private
     * @param {Function} operator 需要进行的操作函数.
     * @param {number} [defaultValue] 默认结果值.
     * @returns {Function} 返回新的操作方法.
     * 
     */
    function createMathOperation(operator, defaultValue) {
      return function(value, other) {
        var result;
        if (value === undefined && other === undefined) { //如果没有传参,返回默认值
          return defaultValue;
        }
        if (value !== undefined) {
          result = value;
        }
        if (other !== undefined) {
          if (result === undefined) {//如果第一个参数为undefined,返回第二个参数
            return other;
          }
          if (typeof value == 'string' || typeof other == 'string') { //如果有字符串全部转换为字符串,否则全部转化为数字
            value = baseToString(value);
            other = baseToString(other);
          } else {
            value = baseToNumber(value);
            other = baseToNumber(other);
          }
          result = operator(value, other);//调用操作函数
        }
        return result;// 返回执行结果
      };
    }
    
    module.exports = createMathOperation;

    减法,乘法,除法也是基于这个方法而来的

    _.divide(dividend, divisor)

    两个数值相除
    //divide.js
    
    var createMathOperation = require('./_createMathOperation');//包装方法
    
    /**
     *
     * @param {number} dividend 被除数.
     * @param {number} divisor 除数.
     * @returns {number} 返回执行结果.
     * @example
     *
     * _.divide(6, 4);
     * // => 1.5
     */
    var divide = createMathOperation(function(dividend, divisor) { //和add方法类似
      return dividend / divisor;
    }, 1);
    
    module.exports = divide;

    _.multiply(multiplier, multiplicand)

    两个数值想乘.
    //multiply.js
    
    var createMathOperation = require('./_createMathOperation');
    
    /**
     *
     * @param {number} multiplier 相乘的第一个值.
     * @param {number} multiplicand 相乘的第二个值.
     * @returns {number} 返回执行结果.
     * @example
     *
     * _.multiply(6, 4);
     * // => 24
     */
    var multiply = createMathOperation(function(multiplier, multiplicand) {//和add方法类似
      return multiplier * multiplicand;
    }, 1);
    
    module.exports = multiply;

    _.subtract(minuend, subtrahend)

    两个数值相减.
    //subtract.js
    
    var createMathOperation = require('./_createMathOperation');
    
    /**
     *
     * @param {number} minuend 被减数.
     * @param {number} subtrahend 减数.
     * @returns {number} 返回执行结果.
     * @example
     *
     * _.subtract(6, 4);
     * // => 2
     */
    var subtract = createMathOperation(function(minuend, subtrahend) {//和add方法类似
      return minuend - subtrahend;
    }, 0);
    
    module.exports = subtract;

    _.ceil(number, [precision=0])

    对数值进行上舍入.
    //ceil.js
    
    var createRound = require('./_createRound'); //约数构造器
    
    /**
     *
     * @static
     * @memberOf _
     * @since 3.10.0
     * @category Math
     * @param {number} number 需要处理的数字.
     * @param {number} [precision=0] 精确的位数.
     * @returns {number} 返回舍入之后的数值.
     * @example
     *
     * _.ceil(4.006);
     * // => 5
     *
     * _.ceil(6.004, 2);
     * // => 6.01
     *
     * _.ceil(6040, -2);
     * // => 6100
     */
    var ceil = createRound('ceil'); //调用createRound,传入ceil
    
    module.exports = ceil;

    这个方法依赖于createRound方法

    //_createRound.js
    
    var toInteger = require('./toInteger'), //转化为整型
        toNumber = require('./toNumber'), //转化为数字
        toString = require('./toString'); //转化为字符串
    
    /* Built-in method references for those with the same name as other `lodash` methods. */
    var nativeMin = Math.min;
    
    /**
     * 创建一个约数方法.
     *
     * @private
     * @param {string} methodName 在Math方法中对应的方法名.
     * @returns {Function} 返回新的约数方法.
     */
    function createRound(methodName) {
      var func = Math[methodName]; //对应方法
      return function(number, precision) {
        number = toNumber(number); //转化为数字
        precision = precision == null ? 0 : nativeMin(toInteger(precision), 292);
        if (precision) {
          //用指数表示避免浮点问题
          var pair = (toString(number) + 'e').split('e'),
              value = func(pair[0] + 'e' + (+pair[1] + precision));//先扩大10的precision倍,再调用func方法
    
          pair = (toString(value) + 'e').split('e');
          return +(pair[0] + 'e' + (+pair[1] - precision));//缩小10的precision倍,还原数值
        }
        return func(number);
      };
    }
    
    module.exports = createRound;

    既然有ceil方法,那就必然有floor和round方法

    _.floor(number, [precision=0])

    对一个数值进行下舍入.
    //floor.js
    
    var createRound = require('./_createRound');
    
    /**
     *
     * @param {number} number 需要处理的数值.
     * @param {number} [precision=0] 精确的位数.
     * @returns {number} 返回处理后的数值.
     * @example
     *
     * _.floor(4.006);
     * // => 4
     *
     * _.floor(0.046, 2);
     * // => 0.04
     *
     * _.floor(4060, -2);
     * // => 4000
     */
    var floor = createRound('floor');//调用createRound,传入floor
    
    module.exports = floor;

    _.round(number, [precision=0])

    对一个数值进行四舍五入.
    //round.js
    
    var createRound = require('./_createRound');
    
    /**
     *
     * @param {number} number 需要处理的数值.
     * @param {number} [precision=0] 精确的位数.
     * @returns {number} 返回处理之后的数值.
     * @example
     *
     * _.round(4.006);
     * // => 4
     *
     * _.round(4.006, 2);
     * // => 4.01
     *
     * _.round(4060, -2);
     * // => 4100
     */
    var round = createRound('round');//调用createRound,传入round
    
    module.exports = round;

    _.max(array)

    计算数组中的最大值.
     
    //max.js
    
    var baseExtremum = require('./_baseExtremum'), //基础求极值方法
        baseGt = require('./_baseGt'), //大于比较方法,baseGt(3,1) => true, baseGt(3, 4) => false
        identity = require('./identity'); //返回第一个参数
    
    /**
     *
     * @param {Array} array 需要处理的数组.
     * @returns {*} 返回数组中的最大值.
     * @example
     *
     * _.max([4, 2, 8, 6]);
     * // => 8
     *
     * _.max([]);
     * // => undefined
     */
    function max(array) {
      return (array && array.length)
        ? baseExtremum(array, identity, baseGt) //调用baseExtremum方法
        : undefined;
    }
    
    module.exports = max;

    依赖于baseExtremum方法

    //_baseExtremum.js
    
    var isSymbol = require('./isSymbol');
    
    /**
     * max和min的基本实现,接受一个比较方法决定这个极值
     *
     * @private
     * @param {Array} array 需要处理的数组.
     * @param {Function} iteratee 对每个元素调用的迭代器.
     * @param {Function} comparator 比较两个值得比较方法.
     * @returns {*} 返回这个极值.
     */
    function baseExtremum(array, iteratee, comparator) {
      var index = -1,
          length = array.length;
    
      while (++index < length) { //对数组进行遍历
        var value = array[index],
            current = iteratee(value);//当前用于比较的值
    
        if (current != null && (computed === undefined
              ? (current === current && !isSymbol(current))
              : comparator(current, computed)
            )) { //对当前值和上一轮的最值进行比较
          var computed = current,//当前的最值
              result = value; //最值对应的元素
        }
      }
      return result;//返回对应的元素
    }
    
    module.exports = baseExtremum;

    _.min(array)

    计算数组中的最小值.
    //min.js
    
    var baseExtremum = require('./_baseExtremum'),
        baseLt = require('./_baseLt'),//小于比较方法,baseGt(3,1) => false, baseGt(3, 4) => true
        identity = require('./identity');
    
    /**
     *
     * @param {Array} 需要处理的数组.
     * @returns {*} 返回最小值.
     * @example
     *
     * _.min([4, 2, 8, 6]);
     * // => 2
     *
     * _.min([]);
     * // => undefined
     */
    function min(array) {
      return (array && array.length)
        ? baseExtremum(array, identity, baseLt)
        : undefined;
    }
    
    module.exports = min;

    _.maxBy(array, [iteratee=_.identity])

    和max方法很像,除了它接受一个遍历方法对每个元素调用,生成用于比较的值,遍历方法接受一个参数:value.
    //maxBy.js
    
    var baseExtremum = require('./_baseExtremum'),
        baseGt = require('./_baseGt'),
        baseIteratee = require('./_baseIteratee'); //基础遍历方法,支持熟悉简写
    
    /**
     * 
     *
     * @param {Array} array 需要处理的数组.
     * @param {Function} [iteratee=_.identity] 遍历方法.
     * @returns {*} 返回对应的最大值.
     * @example
     *
     * var objects = [{ 'n': 1 }, { 'n': 2 }];
     *
     * _.maxBy(objects, function(o) { return o.n; });
     * // => { 'n': 2 }
     *
     * // The `_.property` iteratee shorthand.
     * _.maxBy(objects, 'n');
     * // => { 'n': 2 }
     */
    function maxBy(array, iteratee) { 
      return (array && array.length)
        ? baseExtremum(array, baseIteratee(iteratee, 2), baseGt) //调用baseExtremum,并且传入遍历方法,和大于比较方法
        : undefined;
    }
    
    module.exports = maxBy;

    _.minBy(array, [iteratee=_.identity])

    和max方法很像,除了它接受一个遍历方法对每个元素调用,生成用于比较的值,遍历方法接受一个参数:value.
    //minBy.js
    
    var baseExtremum = require('./_baseExtremum'),
        baseIteratee = require('./_baseIteratee'),
        baseLt = require('./_baseLt');
    
    /**
     * 
     *
     * @param {Array} array 需要处理的数组.
     * @param {Function} [iteratee=_.identity] 遍历方法.
     * @returns {*} 返回对应的最小值.
     * @example
     *
     * var objects = [{ 'n': 1 }, { 'n': 2 }];
     *
     * _.minBy(objects, function(o) { return o.n; });
     * // => { 'n': 1 }
     *
     * // The `_.property` iteratee shorthand.
     * _.minBy(objects, 'n');
     * // => { 'n': 1 }
     */
    function minBy(array, iteratee) {
      return (array && array.length)
        ? baseExtremum(array, baseIteratee(iteratee, 2), baseLt) //调用baseExtremum,并且传入遍历方法,和小于比较方法
        : undefined;
    }
    
    module.exports = minBy;

    _.sum(array)

    对数组元素进行求和.
    // sum.js
    var baseSum = require('./_baseSum'), //基础求和方法
        identity = require('./identity'); //返回第一个参数
    
    /**
     *
     * @param {Array} array 需要处理的数组.
     * @returns {number} 返回总和.
     * @example
     *
     * _.sum([4, 2, 8, 6]);
     * // => 20
     */
    function sum(array) {
      return (array && array.length)
        ? baseSum(array, identity) //调用baseSum方法
        : 0;
    }
    
    module.exports = sum;

    依赖于baseSum方法

    // _baseSum.js
    
    /**
     * 基础求和方法,不支持遍历器简写
     *
     * @private
     * @param {Array} array 需要处理的数组.
     * @param {Function} iteratee 遍历方法,对每个元素调用.
     * @returns {number} 返回总和.
     */
     function baseSum(array, iteratee) {
      var result,
          index = -1,
          length = array.length;
    
      while (++index < length) { //遍历数组
        var current = iteratee(array[index]); //对当前值调用遍历方法
        if (current !== undefined) {
          result = result === undefined ? current : (result + current); //执行相加
        }
      }
      return result;//返回结果
    }
    
    module.exports = baseSum;

    _.sumBy(array, [iteratee=_.identity])

    求和方法,和sum很像,除了它接受一个遍历方法对每个元素调用生成用于相加的方法.
    //sumBy.js
    
    var baseIteratee = require('./_baseIteratee'),
        baseSum = require('./_baseSum');
    
    /**
     *
     * @param {Array} array 需要处理的数组.
     * @param {Function} [iteratee=_.identity] 遍历方法.
     * @returns {number} 返回总和.
     * @example
     *
     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
     *
     * _.sumBy(objects, function(o) { return o.n; });
     * // => 20
     *
     * // The `_.property` iteratee shorthand.
     * _.sumBy(objects, 'n');
     * // => 20
     */
    function sumBy(array, iteratee) {
      return (array && array.length)
        ? baseSum(array, baseIteratee(iteratee, 2)) //调用baseSum方法,传入遍历器,并且支持属性简写
        : 0;
    }
    
    module.exports = sumBy;

    _.mean(array)

    求数组所有元素的平均值.
    //mean.js
    
    var baseMean = require('./_baseMean'), //基础mean方法
        identity = require('./identity'); //返回第一个参数
    
    /**
     * 求数组所有元素的平均值.
     *
     * @param {Array} array 需要处理的数组.
     * @returns {number} 返回平均值.
     * @example
     *
     * _.mean([4, 2, 8, 6]);
     * // => 5
     */
    function mean(array) {
      return baseMean(array, identity); //调用baseMean方法
    }
    
    module.exports = mean;

     

    依赖于baseMean方法

    //_baseMean.js
    
    var baseSum = require('./_baseSum'); //基础求和方法
    
    /** Used as references for various `Number` constants. */
    var NAN = 0 / 0;
    
    /**
     * 基础求平均值方法,不支持遍历器的简写
     *
     * @private
     * @param {Array} array 需要处理的数组.
     * @param {Function} iteratee 遍历器对每个元素调用.
     * @returns {number} 返回平均值.
     */
    function baseMean(array, iteratee) {
      var length = array == null ? 0 : array.length;
      return length ? (baseSum(array, iteratee) / length) : NAN; //调用baseSum进行求和,再进行求平均值,如果没有元素,则返回NaN
    }
    
    module.exports = baseMean;

    _.meanBy(array, [iteratee=_.identity])

    求平均值方法,和mean方法类似.除了它接受一个遍历方法对每个元素调用,生成用于计算的值,遍历方法接受一个参数:value.
    // meanBy.js
    
    var baseIteratee = require('./_baseIteratee'),
        baseMean = require('./_baseMean');
    
    /**
     * 求平均值方法,和mean方法类似.除了它接受一个遍历方法对每个元素调用,生成用于计算的值,遍历方法接受一个参数:value.
     *
     * @param {Array} array 需要处理的数组.
     * @param {Function} [iteratee=_.identity] 遍历器对每个元素调用。
     * @returns {number} 返回这个平均值.
     * @example
     *
     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
     *
     * _.meanBy(objects, function(o) { return o.n; });
     * // => 5
     *
     * // The `_.property` iteratee shorthand.
     * _.meanBy(objects, 'n');
     * // => 5
     */
    function meanBy(array, iteratee) {
      return baseMean(array, baseIteratee(iteratee, 2));//调用baseMean方法,传入遍历器,并且支持属性简写。
    }
    
    module.exports = meanBy;
  • 相关阅读:
    CSS 样式清单整理
    JavaScript常用方法封装
    c# 异常:值不能为 null。 参数名: source
    iframe重新加载
    jquery 获取 父级 iframe 里的控件对象
    添加外键约束
    LinQ to entities 不能识别方法“system.string.ToString(system.String)”.因此该方法无法转换为存储表达式
    c# pcm
    .Net Core 2.0 App中读取appsettings.json
    c# 泛型demo
  • 原文地址:https://www.cnblogs.com/wandiao/p/7853611.html
Copyright © 2011-2022 走看看