复习JS基础之分组、函数柯里化、对象的字符串化

1,534 阅读2分钟

一. 分组

思路

将函数执行结果用作分组的key

解决方法

  1. 直接通过数组的forEach或其它的可迭代的方法,循环迭代其每一项,将其作为参数传入执行函数fn,将执行结果用作需要分组的key
  2. 根据key进行分组:判断当前key是否存在,并将循环的的当前项追加到对应的分组项中去

实现

/**
 * @param {Function} fn
 * @return {Array}
 */
Array.prototype.groupBy = function(fn) {
    let results = {};
    let len = this.length;
    this.forEach((curr) => {
        let key = fn(curr);
        results[key] ? results[key].push(curr) : results[key] = [curr];
    });
    return results;
};

/**
 * [1,2,3].groupBy(String) // {"1":[1],"2":[2],"3":[3]}
 */

二. 函数柯里化

思路

将内外函数的参数进行合并到一个数组中,看其长度是否到达传入的fn函数的长度,到达就执行fn,没有就继续递归

解决方法

  1. 将内外函数的参数就行合并到一个数组args中
  2. 用args的长度和fn的长度进行比较,大于或者相等,就执行fn函数,否则,就递归curried函数

实现

/**
 * @param {Function} fn
 * @return {Function}
 */
var curry = function(fn, ...outerArgs) {
    const args = outerArgs;
    return function curried(...innerArgs) {
        args.push(...innerArgs);
        if (args.length >= fn.length) {
            return fn(...args);
        }
        return curried;
    };
};

/**
 * function sum(a, b) { return a + b; }
 * const csum = curry(sum);
 * csum(1)(2) // 3
 */

三. 对象的字符串化

思路

递归对象中每一个对象属性

解决方法

  1. 判断是否是基本类型null、number、boolean,如果是的话,直接返回其值
  2. 判断是否是字符串,如果是的话,需要将其转换为双引号包裹的字符串
  3. 对其它一些特殊对象进行特殊处理,这里之考虑了日期、正则等
  4. 对数组和非数组对象进行循环迭代其属性,并通过递归循环将其没一项转换为字符串对象

实现

/**
 * @param {any} object
 * @return {string}
 */
var jsonStringify = function(object) {
     if (object === null || ['number', 'boolean'].includes(typeof object)) {
        return object;
    }
    if (typeof object === 'string') return `"${object}"`;
    if (['undefined', 'symbol', 'function'].includes(typeof object)) {
        return undefined;
    }
    if (object instanceof RegExp) {
        return `{}`;
    }
    if (object instanceof Date) {
        return `"${object.toISOString()}"`;
    }
    if (Array.isArray(object)) {
        let len = object.length;
        let result = object.reduce(function (prev, curr, i) {
            let item = ['undefined', 'symbol', 'function'].includes(typeof curr) ? null : curr;
            return prev + `${jsonStringify(item)}${i < len - 1 ? ',' : ''}`;
        }, '');
        return `[${result}]`;
    } else {
        const result = [];
        for(let k in object) {
            let item = object[k];
            if (!['undefined', 'symbol', 'function'].includes(typeof item)) {
                result.push(`"${k}":${jsonStringify(item)}`);
            }
        }
        return `{${result.join(',')}}`;
    }
};