外观
其他
实现对象深拷贝
javascript
function deepClone(obj) {
// if not object
if (typeof obj !== "object") {
return obj;
}
// if null
if (obj === null) {
return null;
}
// if array
if (Array.isArray(obj)) {
return obj.map((elem) => deepClone(elem));
}
// if obj
const tempObj = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
tempObj[key] = deepClone(obj[key]);
}
}
return tempObj;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
数组扁平化
问题
- 将数组中的所有数组元素扁平化成顶层元素,返回新数组,不修改原数组
- 增加去重功能,重复的为基本数据类型的元素不显示(只是不显示重复的部分,即如果有两个2,第二个重复的2不显示,第一个2还是要显示的)
解答
javascript
function flattenArray(arr) {
if (!Array.isArray(arr)) {
throw new TypeError("You should pass in an Array parameter");
}
const tempArr = [];
const tempObj = {};
void (function recurison(item) {
if (Array.isArray(item)) {
item.forEach(recurison);
} else {
if (typeof item === "object") {
tempArr.push(item);
} else if (!tempObj[item]) {
tempArr.push(item);
tempObj[item] = true;
}
}
})(arr);
return tempArr;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
数字数组奇偶排序
问题
将数组中奇数放在右边,偶数放在左边,不允许使用额外空间。
说明:从一个数组中间删除元素splice的运行代价是比较大的。
方案
javascript
const arr = [1, 4, 5, 2, 3, 7, 8];
arr.sort(function (a, b) {
return a % 2 !== 0;
});
1
2
3
4
2
3
4
求数组中第二大的数
问题
要求:
- 不能对这个数组进行整体排序;
- 若要用循环,只能一重循环;
- 不使用额外空间。
解答
思路:把最大的数字标记为null,然后再求此时的最大数字。
javascript
const arr = [1, 3, 5, 2, 7, 6];
arr[arr.indexOf(Math.max.apply(null, arr))] = null;
Math.max.apply(null, arr);
1
2
3
2
3
90度旋转二维数组
javascript
const rawArr = [
["1", "2", "3", "4", "5"],
["6", "7", "8", "9", "a"],
["b", "c", "d", "e", "f"],
["g", "h", "i", "j", "k"],
["l", "m", "n", "o", "p"],
];
1
2
3
4
5
6
7
2
3
4
5
6
7
使用新数组再覆盖原数组
如果直接先生成一个新数组, 然后逐个将旧数组里的元素赋值到新数组中的对应位置,那就很简单了。
先列数据看规律:
- (0, 0) => (0, 4)
- (0, 1) => (1, 4)
- (0, 2) => (2, 4)
- (0, 3) => (3, 4)
- (0, 4) => (4, 4)
- ...
- (2, 0) => (0, 2)
- (2, 1) => (1, 2)
- (2, 2) => (2, 2)
- (2, 3) => (3, 2)
- (2, 4) => (4, 2)
- ...
- (4, 0) => (0, 0)
- (4, 1) => (1, 0)
- (4, 2) => (2, 0)
- (4, 3) => (3, 0)
- (4, 4) => (4, 0)
可以看出规律是:oldArray(x, y) => newArray(y, 5 - 1 - x)
javascript
const rawArr = [
["1", "2", "3", "4", "5"],
["6", "7", "8", "9", "a"],
["b", "c", "d", "e", "f"],
["g", "h", "i", "j", "k"],
["l", "m", "n", "o", "p"],
];
function rotate90(arr) {
const length = arr.length;
// 直接这样写是不行的,5个子数组实际对应的是同一个对象,修改一个其实是5个子数组里的值都变了
// const tempArr = new Array(length).fill(new Array(length))
// 这里去掉fill(1)的话就无法构造成二维数组了
const tempArr = new Array(5).fill(1).map(() => new Array(5));
arr.forEach((row, rowIdx) => {
row.forEach((col, colIdx) => {
tempArr[colIdx][length - rowIdx - 1] = arr[rowIdx][colIdx];
console.log(
`(${rowIdx}, ${colIdx}) => (${colIdx}, ${length - rowIdx - 1})`,
);
});
});
return tempArr;
}
console.log(rotate90(rawArr));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
画星号
问题描述
实现一个函数,入参为数字 n
,输出如下图所示的字符串。
解决方案
javascript
function drawAsterisk(n) {
function getRepeatStr(num, repeatStr) {
return new Array(num).fill(repeatStr).join("");
}
function log(str) {
console.log(str);
}
const arr = [];
const sumLength = 2 * n - 1;
for (let i = 0; i < n - 1; i++) {
const numOfStar = 2 * i + 1;
const numOfSpaces = sumLength - numOfStar;
const sideSpaces = getRepeatStr(numOfSpaces / 2, " ");
arr.push(sideSpaces + getRepeatStr(numOfStar, "*") + sideSpaces);
}
// 画上半部分
arr.forEach(log);
// 画中间一行
console.log(getRepeatStr(2 * n - 1, "*"));
// 下半部分与上半部分层是轴对称的,直接 `reverse()` 反转下就可以直接用
arr.reverse();
// 画下半部分
arr.forEach(log);
}
drawAsterisk(2);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26