原题链接
https://leetcode.cn/problems/group-by/
题目解析
题目要求我们为数组原型添加一个名为groupBy
的方法,该方法接受一个函数fn
作为参数,并返回一个对象。这个对象的键是fn
函数的返回值,值是与该键相关的数组元素的数组。
解题思路
解法1:使用reduce
方法
/**
* 使用 reduce 方法实现 groupBy
* @param {Function} fn - 用于生成分组键的函数
* @return {Object} - 分组后的对象
*/
Array.prototype.groupBy = function(fn) {
return this.reduce((res, curr) => {
// 使用 fn 函数计算当前元素的键
const key = fn(curr);
// 如果结果对象中还没有这个键,就创建一个新数组
// 然后将当前元素添加到这个数组中
(res[key] ??= []).push(curr);
return res;
}, {});
};
可以进一步简写成:
/**
* @param {Function} fn
* @return {Array}
*/
Array.prototype.groupBy = function(fn) {
return this.reduce((res, curr) => ((res[fn(curr)] ??= []).push(curr), res), {})
};
优点:
-
简洁性:
reduce
是JavaScript数组的一个高阶函数,它可以简洁地对数组进行迭代并返回一个累积结果。 - 函数式编程:这种方法采用了函数式编程的风格,使得代码更加紧凑。
缺点:
-
可读性:对于不熟悉
reduce
方法的开发者来说,可能需要花一些时间来理解它的工作原理。
解法2:使用for...of
循环
/**
* 使用 for...of 循环实现 groupBy
* @param {Function} fn - 用于生成分组键的函数
* @return {Object} - 分组后的对象
*/
Array.prototype.groupBy = function(fn) {
let obj = {};
for (const item of this) {
const key = fn(item);
// 如果结果对象中还没有这个键,就创建一个新数组
if (!obj[key]) {
obj[key] = [item];
} else {
// 否则,将当前元素添加到与该键相关的数组中
obj[key].push(item);
}
}
return obj;
};
优点:
- 可读性:这种解法的可读性很好,它明确地描述了如何构建结果对象,并且没有使用任何高阶函数或复杂的语法。
- 直观性:这种解法使用了传统的循环结构,对于大多数开发者来说都很熟悉。
缺点:
-
代码长度:与
reduce
方法相比,这种方法的代码稍微长一些。
总结
两种解法在效率上都是相似的,但在可读性和简洁性上有所不同。如果你更喜欢函数式编程的风格,并且希望代码尽可能地简洁,那么解法1可能更适合你。如果你希望代码更加直观和易于理解,那么解法2可能更适合你。总的来说,选择哪种解法取决于你的个人喜好和项目的需求。在实际开发中,考虑到代码的可读性和维护性通常是很重要的。
网友评论