# 笔试题
1. 实现数组扁平化
- 偶然发现了yield*的用法,天才级别的扁平化方式
function* iterTree(tree){
if(Array.isArray(tree)){
for(let i = 0 ;i<tree.length;i++){
yield* iterTree(tree[i]);
}
}else{
yield tree;
}
}
let arr1 = [1, 2, ['a', 'b', ['中', '文', [1, 2, 3, [11, 21, 31]]]], 3];
for (const x of iterTree(tree)) {
console.log(x);
}
- 利用Array.some方法判断数组中是否还存在数组,es6展开运算符连接数组
function iterTree2(arr) {
while (arr.some(item => Array.isArray(item))) {
arr = [].concat(...arr);
}
return arr;
}
console.log(iterTree2(arr1));
利用array数组的reduce属性,reduce回调函数有四个参数,reduce(( previousValue,currentValue,currentIndex,array)=>{},initial)
提供了initial的值的时候,previousValue为initial的大小,currentValue为数组的第一个元素值 没有提供initial的值的时候,preciousValue为数组第一个元素的值,currentValue为第二个元素的值,此后每执行一次,previousValue
function iterTree3(arr) {
var newArr = arr.reduce((prev, current) => {
return prev.concat(Array.isArray(current) ? iterTree3(current) : current)
}, []);
return newArr;
}
console.log(iterTree3(arr1));
- es6中的flat函数也可以实现数组的扁平化
let arr1 = [1,2,['a','b',['中','文',[1,2,3,[11,21,31]]]],3];
console.log( arr1.flat( Infinity ) );
2. 实现千分位
- 最最便捷的实现方式:toLocaleString()
// 注:只针对数字格式有效!
let num = 1234567890;
num.toLocaleString(); // "1,234,567,890"
- 正则匹配
// 正则匹配方法一
let num = 1234567890;
let reg = /\d{1,3}(?=(\d{3})+$)/g;
String(num).replace(reg, '$&,'); //"1,234,567,890"
// 正则匹配方法二
let num = 1234567890;
let reg = /\B(?=(\d{3})+$)/g;
String(num).replace(reg, ','); //"1,234,567,890"
// 或
const thousands = (str) => {
// 提取整数、小数部分
let nums = str.match(/\d+/g)
// 利用零宽度正预测先行断言,匹配千分位
let newStr = nums[0].replace(/\d{1,3}(?=(\d{3})+$)/g, val => {
return val + ','
})
return newStr + (nums[1] ? '.' + nums[1] : '')
}
console.log(thousands('1123343412')) // 1,123,343,412
console.log(thousands('12123343412.')) // 12,123,343,412
console.log(thousands('123123343412.23')) // 123,123,343,412.23
console.log(thousands('123123343412.0923843')) // 123,123,343,412.0923843
- for循环
// for循环方法一
function format(num){
num = String(num);//数字转字符串
let str = '';//字符串累加
for (let i = num.length- 1, j = 1; i >= 0; i--, j++){
if (j%3 == 0 && i != 0){ //每隔三位加逗号,过滤正好在第一个数字的情况
str += num[i] + ','; //加千分位逗号
continue;
}
str += num[i]; //倒着累加数字
}
return str.split('').reverse().join(""); //字符串=>数组=>反转=>字符串
}
let num = 1234567890;
format(num); //"1,234,567,890"
// for循环方法二
function format(num){
num = String(num);//数字转字符串
let str = '';//字符串累加
for (let i = num.length- 1, j = 1; i >= 0; i--, j++){
if (j%3 == 0 && i != 0){ //每隔三位加逗号,过滤正好在第一个数字的情况
str = ',' + num[i] + str; //加千分位逗号
continue;
}
str = num[i] + str; //累加数字
}
return str;
}
let num = 1234567890;
format(num); //"1,234,567,890"
- slice+while循环
function format(num) {
let arr = [],
str = String(num),
count = str.length;
while (count >= 3) {
arr.unshift(str.slice(count - 3, count));
count -= 3;
}
// 如果是不是3的倍数就另外追加到上去
if(str.length % 3) arr.unshift(str.slice(0, str.length % 3));
return arr.toString();
}
let num = 1234567890;
format(num); //"1,234,567,890"
- reduce
function format(num) {
var str = num+'';
return str.split("").reverse().reduce((prev, next, index) => {
return ((index % 3) ? next : (next + ',')) + prev;
})
}
let num = 1234567890;
format(num); //"1,234,567,890"
当然也存在很多类似的写法
3. 平级父子结构树型化(tree)
var data = [
{ id: 1, name: "办公管理", pid: 0 },
{ id: 2, name: "请假申请", pid: 1 },
{ id: 3, name: "出差申请", pid: 1 },
{ id: 4, name: "请假记录", pid: 2 },
{ id: 5, name: "系统设置", pid: 0 },
{ id: 6, name: "权限管理", pid: 5 },
{ id: 7, name: "用户角色", pid: 6 },
{ id: 8, name: "菜单设置", pid: 6 },
];
var data = [
{id: 1, name: "办公管理", pid: 0 ,
children:[
{ id: 2, name: "请假申请", pid: 1,
hildren:[
{ id: 4, name: "请假记录", pid: 2 },
],
},
{ id: 3, name: "出差申请", pid: 1},
]
},
{id: 5, name: "系统设置", pid: 0 ,
children:[
{ id: 6, name: "权限管理", pid: 5,
hildren:[
{ id: 7, name: "用户角色", pid: 6 },
{ id: 8, name: "菜单设置", pid: 6 },
]
},
]
},
];
// js转换为上面数据集
function toTree(data) {
// 删除 所有 children,以防止多次调用
data.forEach(function (item) {
delete item.children;
});
// 将数据存储为 以 id 为 KEY 的 map 索引数据列
var map = {};
data.forEach(function (item) {
map[item.id] = item;
});
// console.log(map);
var val = [];
data.forEach(function (item) {
// 以当前遍历项,的pid,去map对象中找到索引的id
var parent = map[item.pid];
// 好绕啊,如果找到索引,那么说明此项不在顶级当中,那么需要把此项添加到,他对应的父级中
if (parent) {
(parent.children || ( parent.children = [] )).push(item);
} else {
//如果没有在map中找到对应的索引ID,那么直接把 当前的item添加到 val结果集中,作为顶级
val.push(item);
}
});
return val;
}
console.log(toTree(data))
4. 手写new
// 创建一个新对象
// 将构造函数中的this指向该对象
// 执行构造函数代码(给新对象添加属性和方法)
// 返回者着新对象
function _new(){
var obj = new Object(); // 创建空对象
var func = [].shift.apply(arguments);
obj.__proto__ = func.prototype; // 空对象原型链指向构造函数原型
var ret = func.apply(obj,arguments); //取得构造函数的返回值
return typeof ret=="object"? ret : obj; //如果返回值是一个对象就返回该对象,否则返回构造函数的一个实例对象
}
5. 手写冒泡排序
// 1. 使用冒泡排序算法将数组var a = ['B','A','E','C','D'];排序为var a=['A','B','C','D','E'];请使用javascript写出全过程。
function bubbleSort(arr) {
var len = arr.length;
for (var i = 0; i < len; i++) {
for (var j = 0; j < len - 1 - i; j++) {
if (arr[j] > arr[j+1]) { //相邻元素两两对比
var temp = arr[j+1]; //元素交换
arr[j+1] = arr[j];
arr[j] = temp;
}
}
}
return arr;
}
← 面试