上一篇文章能受到这样的关注度,感谢各位同窗的点赞和评论,给了我不少动力继续去更新这个系列,也但愿它们可以对你们有必定的帮助。蟹蟹你们。javascript
废话很少说,直接上题。vue
let arr = [
[
['1-7', '2-6'],
'4-6',
[
['2-0', '1-4'],
['3-9'],
'4-5',
],
]
]
// Q1: 完成数组 flat 函数
function flat(arr) {
// code
return arr
}
arr = flat(arr);
console.log(arr);
// Q2: 计算 arr 中全部的值:'1-7' => 1 * 7 = 7, 返回一个数字组成的数组
function calc(arr) {
// code
return arr;
}
arr = calc(arr);
console.log(arr);
// Q3: 对这个数组排序和去重
function sortAndReduce(arr) {
// code
return arr;
}
arr = sortAndReduce(arr);
console.log(arr);
复制代码
这个数组结构比较深,这应该是整个题目的考点所在。看这个样子应该是须要用递归,不!应该还有更好的方法,🤔那就使用ES 2019 的 Array.prototype.flat 函数吧!而后被面试官一票否决。在涂涂改改和思考的时间中,面试官问了个人思路结束了这个问题。java
若是有对递归不太熟悉的同窗,能够看看个人读书笔记【算法图解】读书笔记:第3章 递归。react
递归的核心就在于两步:找到基线条件和递归条件。git
function flat(arr) {
const result = []; // 利用闭包缓存咱们的结果
function _flat(arr) {
arr.forEach(element => {
if(Array.isArray(element)) { // 递归条件
_flat(element);
} else { // 基准条件
result.push(element); // 将符合结果的值推入咱们的结果数组中
}
})
}
_flat(arr);
arr = result;
return arr;
}
// 更加简练的版本
// 感谢 @zwlafk
const flat = arr => [].concat(...arr.map(v => Array.isArray(v) ? flat(v) : v));
复制代码
这个思路是我借鉴《图解算法》中广度优先搜索算法章节写的。es6
可是广度优先搜索的结果是不保证顺序的。github
function flat(arr) {
const result = []; // 储存结果
const list = []; // 队列
function _forEach(arr) {
arr.forEach(el => {
if(Array.isArray(el)) list.push(el); // item 若是是数组,将子项依次推入队列
else result.push(el); // item 若是是字符串,将子项推入结果
});
}
_forEach(arr); // 初始化
while(list.length > 0) { // 当 list 长度为0时候,遍历完成
const item = list.shift();
_forEach(item);
}
arr = result;
return arr;
}
复制代码
TODO:web
感谢 @IWANABETHATGUY 同窗的赐教。面试
// 首页你得肯定你的数据里面没有字符串 ',' 哦
function flat(arr) {
arr = arr.toString().split(',')
return arr;
}
// or
// 殊途同归
function flat(arr) {
arr = arr.join(',').split(',')
return arr;
}
复制代码
感谢 @IWANABETHATGUY 同窗的赐教。算法
原理与广度优先搜索相似,经过模拟栈的行为去遍历数组。好处是可以保证有序输出。
function flat(arr) {
let result = [];
let stack = []; // 模拟栈的行为
function forEachRight(arr) {
for (let i = arr.length - 1; i >= 0; i--) { // 先进后出
const item = arr[i];
if(Array.isArray(item)) stack.push(item);
else result.push(item);
}
}
if (arr.length > 0) forEachRight(arr);
while (stack.length > 0) { // 当栈空了,遍历完成
let current = s.pop();
if(current.length > 0) {
forEachRight(current); // 感谢 @Drowned-fish 朋友的建议
}
}
return ret;
}
复制代码
这个问题难度不大,就是考察一些经常使用方法的使用,直接上代码。
function calc(arr) {
// 随手骚一下,不建议 eval
arr = arr.map(el => eval(el.replace('-', '*')));
return arr;
}
// or
function calc(arr) {
arr = arr.map(el => {
const [n1, n2] = el.split('-');
return +n1 * +n2;
});
return arr;
}
复制代码
数组去重能够经过 ES6 的 Set 完成。传送门:ES6 Set 数据结构,不做赘述。数组排序可使用 Array.prototype.sort 函数实现。可是显然考察算法内容,不能直接使用原生方法,并且排序和去重同时完成,性能确定更好。
我以前写过一篇常规的几种排序方法的对比和实现,【JS面试向】选择排序、桶排序、冒泡排序和快速排序简介,这里我直接使用快速排序完成排序和去重工做。
function sortAndReduce(arr) {
if(arr.length < 2) {
return arr;
} else {
const pivot = arr[0]; // 基准值
const lowArr= []; // 小的放左边
const hightArr = []; // 大的放右边
arr.forEach(current => {
if(current > pivot) hightArr.push(current);
else if(current < pivot) lowArr.push(current);
})
return sortAndReduce(lowArr).concat(pivot, sortAndReduce(hightArr));
}
}
复制代码