专栏声明:只求用最简单的,容易理解的方法通过,不求优化,不喜勿喷
2628. 完全相等的 JSON 字符串
题面
给定两个对象 o1 和 o2 ,请你检查它们是否 完全相等 。
对于两个 完全相等 的对象,它们必须包含相同的键,并且相关的值也必须 完全相等 。如果两个对象通过了 === 相等性检查,它们也被认为是 完全相等 的。
你可以假设这两个对象都是 JSON.parse 的输出。换句话说,它们是有效的 JSON 。
请你在不使用 lodash 的 _.isEqual() 函数的前提下解决这个问题。
知识点:
深比较、递归、Json、JS 数据类型
思路
深度比较两个对象,我们比较两个传入的数值,分以下这些情况:
- 如果类型不相等,我们直接判定其不相等
- 如果类型相等,如果不是 object ,我们直接比较他们的值
- 如果是 object,如果是 null 两者都是 null 则相同,否则不同
- 如果是 object 并且都是数组,我们先比较数组的长度,如果相同,我们依次递归比较数组的每一个元素
- 如果是 object 并且是对象,我们先比较每个键值是不是一样,如果键值都相同我们再递归比较每个键值对应的数据是不是相同
代码
var areDeeplyEqual = function (o1, o2) {
if (o1 === null && o2 === null) {
return true;
}
if (typeof o1 != typeof o2) return false;
if (typeof o1 !== 'object') {
return o1 === o2;
} else {
if (o1 instanceof Array !== o2 instanceof Array) return false
if (o1 instanceof Array) {
if (o1.length !== o2.length) return false
for (let i = 0; i < o1.length; i++) {
if (!areDeeplyEqual(o1[i], o2[i])) {
return false;
}
}
} else {
let k1 = Object.keys(o1).sort();
let k2 = Object.keys(o2).sort();
if (k1.join(",") !== k2.join(",")) return false;
for (const key in o1) {
if (!areDeeplyEqual(o1[key], o2[key])) {
return false
}
}
}
}
return true
};
2629. 复合函数
题面
请你编写一个函数,它接收一个函数数组 [f1, f2, f3,…], fn] ,并返回一个新的函数 fn ,它是函数数组的 复合函数 。
[f(x), g(x), h(x)] 的 复合函数 为 fn(x) = f(g(h(x))) 。
一个空函数列表的 复合函数 是 恒等函数 f(x) = x 。
你可以假设数组中的每个函数接受一个整型参数作为输入,并返回一个整型作为输出。
知识点:
数组
思路
获取操作函数的数组,从最内层的操作函数(数组最后一位)依次执行这些操作函数即可
代码
var compose = function (functions) {
return function (x) {
for (var i = functions.length - 1; i >= 0 ; i--) {
x = functions[i](x);
}
return x;
}
};
/**
* const fn = compose([x => x + 1, x => 2 * x])
* fn(4) // 9
*/
2631. 分组
题面
请你编写一段可应用于所有数组的代码,使任何数组调用 array. groupBy(fn) 方法时,它返回对该数组 分组后 的结果。
数组 分组 是一个对象,其中的每个键都是 fn(arr[i]) 的输出的一个数组,该数组中含有原数组中具有该键的所有项。
提供的回调函数 fn 将接受数组中的项并返回一个字符串类型的键。
每个值列表的顺序应该与元素在数组中出现的顺序相同。任何顺序的键都是可以接受的。
请在不使用 lodash 的 _.groupBy 函数的前提下解决这个问题。
知识点:
groupBy 、哈希表
思路
初始化一个对象摸你哈希表,用数组作为 value。
对于每个值,我们使用 fn 操作之后,判定哈希表中有没有对应的键值,如果有,把当前数组插入哈希表的这一键值的数组中,如果没有,创建这个键值,在插入即可
代码
Array.prototype.groupBy = function (fn) {
let obj = {
};
for (var i = 0; i < this.length; i++) {
let k = fn(this[i]).toString();
if(obj[k] == null){
obj[k] = [];
}
obj[k].push(this[i]);
}
return obj;
};
/**
* [1,2,3].groupBy(String) // {"1":[1],"2":[2],"3":[3]}
*/
2632. 柯里化
题面
请你编写一个函数,它接收一个其他的函数,并返回该函数的 柯里化 后的形式。
柯里化 函数的定义是接受与原函数相同数量或更少数量的参数,并返回另一个 柯里化 后的函数或与原函数相同的值。
实际上,当你调用原函数,如 sum(1,2,3) 时,它将调用 柯里化 函数的某个形式,如 csum(1)(2)(3), csum(1)(2,3), csum(1,2)(3),或 csum(1,2,3) 。所有调用 柯里化 函数的方法都应该返回与原始函数相同的值。
知识点:
柯里化
思路
通用模板,先在我们的函数中初始化一个数组,用来保存所有的参数。
我们可以通过函数的 length 属性可以获取他传入的参数总数,柯里化之后也能获取他总共的参数,不论他调用几次。
之后我们通过 arguments 获得每次接收一次调用的参数,把它放在我们的数组中,通过数组的长度和我们的总共参数的数量比较,如果还没调用完毕,我们返回我们的柯里化函数继续接收参数,如果调用完毕,我们将我们的参数列表传入给出的需要柯里化的计算函数返回结果即可。
代码
var curry = function(fn) {
let argv = [];
return function curried() {
for(let a of arguments){
argv.push(a);
}
if(argv.length == fn.length){
return fn(...argv);
}else{
return curried;
}
};
};
/**
* function sum(a, b) { return a + b; }
* const csum = curry(sum);
* csum(1)(2) // 3
*/
2633. 将对象转换为 JSON 字符串
题面
现给定一个对象,返回该对象的有效 JSON 字符串。你可以假设这个对象只包括字符串、整数、数组、对象、布尔值和 null。返回的字符串不能包含额外的空格。键的返回顺序应该与 Object.keys() 的顺序相同。
请你在不使用内置方法 JSON.stringify 的前提下解决这个问题。
知识点:
递归、Json、JS 数据类型
思路
根据我们传入的对象来判断进行操作:
- 如果是传入一个 string,我们直接加上引号返回 json 字符串即可
- 如果传入 null ,我们返回字符串的 null
- 如果传入一个数组
- 我们先构造我们的数组开始符号
[
之后依次遍历数组的每一个元素,递归调用我们的函数,之后判断要不要添加我们的分隔符,
, 遍历结束,我们加上数组的结束符号]
- 如果是对象,我们和数组的操作大同小异,依次遍历每个键值,需要把键值和结果数据都构造出来,用
:
分割,其他操作一致 - 如果不是数组、对象和字符串,我们直接把它转为字符串即可类型即可
- 递归整个对象,拼接字符串返回即可
代码
var jsonStringify = function (object) {
let type = typeof object;
if (type == "string") {
return `"${
object}"`;
} else if (type == 'object') {
if (object == null) {
return "null";
} else if (object instanceof Array) {
let re = "[";
for (var i = 0; i < object.length; i++) {
if (i != 0) {
re += ",";
}
re += jsonStringify(object[i])
}
return re + "]";
} else {
let re = "{";
let keys = Object.keys(object);
for (var i = 0; i < keys.length; i++) {
if (i != 0) {
re += ",";
}
re += `"${
keys[i]}":${
jsonStringify(object[keys[i]])}`;
}
re += "}";
return re;
}
} else {
return "" + object;
}
};