题目一 数组乱序
思路
随机选择一个0到len之间的index,将其与0位元素交换,计算交换过的元素个数,下次除去第一个元素后再次随机选择一个index,不断选择,直到所有的元素都遍历过为止。
知识点:
Math.random(): 获取[0-1)之间的随机数
- 获得[0-10)之间的随机数:
Math.random() * 10 - 获取[0-len)之间的随机数:
Math.random() * len - 获取[1-10]之间的随机数:
Math.random() * 10 + 1 - 获取[2-6)之间的随机数:
Math.random() * (6-2) + 2
这道题容易出问题的点就是随机index的获取
- math.random()取的是带小数点的,需要用Math.floor来向下取整。
- 获取[a-b)之间的随机数:
Math.random() * (b-a) + a
function shuffle(arr) {
const len = arr.length;
let count = 0;
while (count < len) {
const index = Math.floor(Math.random() * (len - count) + count);
[arr[count], arr[index]] = [arr[index], arr[count]];
count++;
}
return arr;
}
function shuttle(arr) {
const len = arr.length;
for (let i = 1; i < len; i++) {
const index = Math.floor(Math.random() * (len - i) + i);
[arr[i], arr[j]] = [arr[j], arr[i]];
}
return arr;
}
function shuttle(arr) {
const len = arr.length;
for (let i = 0; i < len - i; i++) {
const randomIndex = Math.floor(Math.random() * i);
[arr[randomIndex], arr[len - i - 1]] = [arr[len - i - 1], arr[randomIndex]];
}
return arr;
}
shuffle([1, 2, 3, 4]);
题目二 数组扁平化
方法1 递归调用
遍历数组元素,如果当前元素是数组类型,则递归调用,并将结果拼接起来,如果不是,则push到数组中,最后返回结果。
function flatten(arr) {
let result = [];
for (let i = 0; i < arr.length; i++) {
let item = arr[i];
if (Array.isArray(item)) {
result = result.concat(flatten(item));
} else {
result.push(item);
}
}
return result;
}
flatten([1, 2, 3, [4, 5, 6, [7, [8, 9]]]])
如果借助reduce实现
function flatten(arr) {
return arr.reduce((acc, cur) => {
return acc.concat(Array.isArray(cur) ? flatten(cur) : [cur]);
}, []);
}
flatten([1, 2, 3, [4, 5, 6, [7, [8, 9]]]])
如果传入一个depth参数,代表展开多少层,则如下:
function flatten(arr, depth = Infinity) {
return arr.reduce((acc, cur) => {
return acc.concat(Array.isArray(cur) && depth > 0 ? flatten(cur, depth - 1) : [cur])
}, []);
}
方法2 借助toString方法
数组的toString会把数组转化为以逗号分隔的字符串,然后再调用split转化为数组
function flatten(arr) {
return arr.toString().split(',').map(item => +item)
}
flatten([1, 2, 3, [4, 5, 6, [7, [8, 9]]]])
方法3 直接调用es6的flat方法
带有一个可选参数,depth,默认为1,如果要全部展开,传入Infinity
function flatten(arr) {
return arr.flat(Infinity);
}
flatten([1, 2, 3, [4, 5, 6, [7, [8, 9]]]])
方法4 generator方式
没想到吧,还有这种方式
// 生成器函数生成一系列值,然后遍历取值
function *flatten(arr) {
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
yield* flatten(arr[i]);
} else {
yield arr[i];
}
}
}
let result = [];
for (let f of flatten(arr)) {
console.log(f);
result.push(f);
}
题目三 去除数组的重复元素
方法1 双指针法
数组排序,排序之后重复的元素一定是相邻的。
j不断往后遍历,i指向不重复元素的最后一个,
如果i和j对应的元素不相等,j放到i+1的位置,并且i++,j++,否则j++
function removeDuplicate(arr) {
arr.sort((a, b) => a - b);
const len = arr.length;
let i = 0;
for (let j = 1; i < len && j < len; j++) {
if (arr[i] !== arr[j]) {
arr[i+1] = arr[j];
i++;
}
}
return arr.slice(0, i + 1);
}
方法2 set
[...new Set(arr)]
题目四 push实现
Array.prototype.push = function () {
for (let i = 0; i < arguments.length; i++) {
this[this.length] = arguments[i];
}
return this.length;
}
题目五 filter实现
Array.prototype.filter = function(fn) {
let result = [];
for (let i = 0; i < this.length; i++) {
if (fn(this[i])) {
result.push(this[i])
}
}
return result;
}