一. 分组
思路
将函数执行结果用作分组的key
解决方法
- 直接通过数组的forEach或其它的可迭代的方法,循环迭代其每一项,将其作为参数传入执行函数fn,将执行结果用作需要分组的key
- 根据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,没有就继续递归
解决方法
- 将内外函数的参数就行合并到一个数组args中
- 用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
*/
三. 对象的字符串化
思路
递归对象中每一个对象属性
解决方法
- 判断是否是基本类型null、number、boolean,如果是的话,直接返回其值
- 判断是否是字符串,如果是的话,需要将其转换为双引号包裹的字符串
- 对其它一些特殊对象进行特殊处理,这里之考虑了日期、正则等
- 对数组和非数组对象进行循环迭代其属性,并通过递归循环将其没一项转换为字符串对象
实现
/**
* @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(',')}}`;
}
};