其他
实现对象深拷贝
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
画星号
问题描述
实现一个函数,入参为数字 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