实现数组方法
# 实现原生方法
# map
Array.prototype._map = function(callback) {
const arr = this
const result = []
this.forEach((val, index) => {
result.push(callback.call(arr, val, index, arr))
})
return result
}
2
3
4
5
6
7
# reduce
Array.prototype._reduce = function(fn, initval) {
const arr = this
let base = typeof initval === 'undefined' ? arr[0] : initval
let initIndex = typeof initval === 'undefined' ? 1 : 0
arr.slice(initIndex).forEach((val, index) => {
base = fn(base, val, initIndex + index, arr)
})
return base
}
2
3
4
5
6
7
8
9
10
# flat
Array.prototype._flat = function(depth = 1){
let res = [...this]
while(depth && res.some(item => Array.isArray(item))) {
res = [].concat(...res)
depth--
}
return res
}
2
3
4
5
6
7
8
# shuffle
实现一个全排列函数
const arr = [1, 2, 3, 4]
输出:[1, 3, 2, 4]等随机,让每一个元素在自己位置的概率是 1/4
function shuffle(arr) {
for(let i = 0; i < arr.length; i++) {
// 每次生成i - arr.length的随机数
let random = Math.floor(Math.random() * (arr.length - i) + i)
// 交换元素
let temp = arr[i]
arr[i] = arr[random]
arr[random] = temp
}
return arr
}
2
3
4
5
6
7
8
9
10
# 变异考点
# 1. 将数组拍平成二维数组
let arr = [1, 2, [3, 4, 5, [6, 7], 8], 9, 10, [11, [12, 13]]]
查看答案
// 参数是拍平的深度
Array.prototype._flat = function(depth = 1){
let len = this.maxDepLength()
console.log(len)
let count = len - depth < 0 ? len : len - depth
let res = [...this]
while(count && res.some(item => Array.isArray(item))) {
res = [].concat(...res)
count--
}
return res
}
// 计算数组深度
Array.prototype.maxDepLength = function () {
let max = 0
let res = 0
for(let i = 0; i < this.length; i++) {
if(Array.isArray(this[i])) {
res = this[i].maxDepLength()
}
res = max > res ? max : res
}
return res + 1
}
let arr1 = arr._flat(2)
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
27
# 2. 将下列数组拍平
let arr = [1, 2, [3, 4, 5, [6, 7], 8], 9, 10, [11, [12, 13]]]
查看答案
function _flat(arr) {
let result = []
arr.forEach((val) => {
if (!Array.isArray(val)) {
result.push(val)
} else {
result = result.concat(_flat(val))
}
})
return result
}
console.log(_flat(arr))
2
3
4
5
6
7
8
9
10
11
12
13
# 3. 计算数组深度
let arr = [1, 2, [3, 4, 5, [6, 7], 8], 9, 10, [11, [12, 13]]]
查看答案
function maxDepth(arr) {
if (!Array.isArray(arr)) return 0
let res = 0
let max = 0
arr.forEach(val => {
res = maxDepth(val)
max = max >= res ? max : res
})
return max + 1
}
2
3
4
5
6
7
8
9
10
# 4. 实现数组深拷贝
实现函数copy对数组或者对象进行深拷贝
let arr = [1, 2, [3, 4, 5, {a: 6, b: {c: 7}}, 8], 9, 10, [11, [12, 13]]]
const arr1 = copy(arr)
arr1[2][3].b = 2
console.log(arr)
console.log(arr1)
查看答案
function copy(value) {
// 如果是原始数据类型就直接返回
if (!(typeof value === 'object' && value !== null)) return value
let result
// 如果是数组
if (Array.isArray(value)) {
result = []
value.forEach(val => {
result.push(copy(val))
})
// 如果是对象
} else if(Object.prototype.toString.call(value) === '[object Object]') {
result = {}
for(let key in value) {
result[key] = copy(value[key])
}
}
return result
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 5. 扁平化+升序不重复
已知如下数组,编写一个程序将数组扁平化去并除其中重复部分数据,最终得到一个升序且不重复的一维数组。
var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10]
查看答案
- flat扁平化
- 使用 Set 方法去重
- 升序排序
Array.from(new Set(arr.flat(Infinity))).sort((a,b) => { return a - b })
//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
2
# 6. 两个数组合并成一个数组
请把两个数组A和B合并
var A = ['A1', 'A2', 'B1', 'B2', 'C1', 'C2', 'D1', 'D2']
var B = ['A', 'B', 'C', 'D']
合并 为 ['A1', 'A2', 'A', 'B1', 'B2', 'B', 'C1', 'C2', 'C', 'D1', 'D2', 'D']
查看答案
- 双指针,按照B循环
- 判断是否有自己的元素,有指针右移,没有在当前位置插入元素
function concatArr (arr1, arr2) {
const arr = [...arr1]
let curIndex = 0
for (let i = 0; i < arr2.length; i++) {
const RE = new RegExp(arr2[i])
while(curIndex < arr.length) {
++curIndex
if (!RE.test(arr[curIndex])) {
arr.splice(curIndex, 0, arr2[i])
break;
}
}
}
return arr
}
var A = ['A1', 'A2', 'B1', 'B2', 'C1', 'C2', 'D1', 'D2']
var B = ['A', 'B', 'C', 'D']
const arr = concatArr(A, B)
console.log(arr)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 7. 某公司1-12月的销售额对象转化成数组
某公司 1 到 12 月份的销售额存在一个对象里面,如下:
{1:222, 2:123, 5:888}
请把数据处理为如下结构:
[222, 123, null, null, 888, null, null, null, null, null, null, null]
查看答案
- 创建一个长度为12的数组
- 遍历数组,如果在对象中有元素则填入,没有返回null
- Array.from(obj, mapFn, thisArg) 就相当于 Array.from(obj).map(mapFn, thisArg)
- Array.from() (opens new window) 可以通过以下方式来创建数组对象:
- 伪数组对象(拥有一个 length 属性和若干索引属性的任意对象)
- 可迭代对象(可以获取对象中的元素,如 Map和 Set 等)
let obj = {
1: 222,
2: 123,
5: 888
}
// Array.from
const result = Array.from({ length: 12 }).map((_, index) => obj[index + 1] || null);
// 等价于
const result = Array.from(new Array(12), (_, index) => obj[index+1] || null)
console.log(result)
2
3
4
5
6
7
8
9
10
# 8. 给定两个数组,写一个方法来计算它们的交集
例如:给定 nums1 = [1, 2, 2, 1],nums2 = [2, 2]
返回:[2, 2]
查看答案
注意: 这里没有用indexOf而是用的includes,因为[NaN].indexOf(NaN) === -1
var num1 = [1, 2, 2, 1]
var num2 = [2, 2, 3, 4]
var newArr2 = num1.filter((item) => {
return num2.includes(item)
})
console.log(newArr2)
2
3
4
5
6
# 9. 给长度为10的数组分类
随机生成一个长度为 10 的整数类型的数组:
例如 [2, 10, 3, 4, 5, 11, 10, 11, 20]
将其排列成一个新数组,要求新数组形式如下
例如 [[2, 3, 4, 5], [10, 11], [20]]
查看答案
/*
1. 去重、排序
2. 用map记录,之后用values输出
*/
function formArray(arr) {
const sortedArr = Array.from(new Set(arr)).sort((a, b) => a - b);
const map = new Map();
sortedArr.forEach((v) => {
const key = Math.floor(v / 10);
const group = map.get(key) || [];
group.push(v);
map.set(key, group);
});
return [...map.values()];
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 10. 把一个字符串的大小写取反
如何把一个字符串的大小写取反(大写变小写小写变大写),例如 'AbC' 变成 'aBc' const str = 'ADasfads123!@$!@#'
查看答案
function processString(s) {
var arr = s.split('');
var new_arr = arr.map((item) => {
return item === item.toUpperCase() ? item.toLowerCase() : item.toUpperCase();
});
return new_arr.join('');
}
2
3
4
5
6