js笔试题汇总
1.交换2个变量的值
//法一
var a = 1;
var b = 2;
var c;
c = b; //2
b = a; //1;
a = c;
console.log(a, b);
法二:
let [a, b] = [1, 2];
[b, a] = [a, b];
console.log(a, b)
2.求数组的最大值
const arr1 = [3, 1, 6, 9];
// 法一
console.log(Math.max.apply(null, arr1));
// 法二
console.log(Math.max(...arr1));
// 法三
let max = arr1[0];
for (let i = 0; i < arr1.length; i++) {
// if (arr1[i] > max) {
// max = arr1[i];
// }
max = arr1[i] > max ? arr1[i] : max
}
console.log(max);
3.冒泡排序
const arr2 = [5, 4, 3, 2, 1];
// 第一轮for循环 [4,3,2,1,5]
// 第二轮for循环 [3,2,1,4,5]
// 第三轮for循环 [2,1,3,4,5]
// 第四轮for循环 [1,2,3,4,5]
function bSort(arr) {
var len = arr.length;
// 第一层for循环是遍历数组中的每一个元素,比如5
for (var i = 0; i < len - 1; i++) {
// 第二层for循环将5与后面的每一项作比较
for (var j = 0; j < len - 1 - i; j++) {
// 相邻元素两两对比,元素交换,大的元素交换到后面
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
4.获取地址栏参数
function getValue(name) {
let params = location.search.slice(1);
let arrParams = params.split('&')
for (var i = 0; i < arrParams.length; i++) {
var pair = arrParams[i].split("=");
if (pair[0] == name) { return pair[1]; }
}
return (false);
}
let url = 'http://www.runoob.com/index.php?id=1&image=awesome.jpg'
let res = getValue('id');
console.log(res);
5.查询字符串中哪个字符出现的次数最多
let str = 'abbccc';
function getMaxStr(str) {
//obj: {a:1,b:2,c:3}
const obj = {};
for (let i = 0; i < str.length; i++) {
var char = str.charAt(i); //返回指定位置的字符
if (obj[char]) {
obj[char]++; //次数加1
} else {
obj[char] = 1; //若第一次出现,次数记为1
}
}
console.log(obj);
//遍历对象,找到出现次数最多的字符和次数
var max = 0;
var maxChar = null;
for (const key in obj) {
if (max < obj[key]) {
max = obj[key]; //max始终储存次数最大的那个
maxChar = key; //那么对应的字符就是当前的key
}
}
console.log(max);
console.log(maxChar);
return max, maxChar;
}
getMaxStr(str);
6.求数组的交集,并集,差集
求2个数组的交集
let num1 = [1, 2, 3, 4];
let num2 = [4, 5, 6, 7, 3];
// 法一
function fn1(arr1, arr2) {
var mixedArr = [];
for (var i = 0; i < arr1.length; i++) {
if (arr2.includes(arr1[i])) {
mixedArr.push(arr1[i]);
}
}
console.log('mixedArr', mixedArr);
return mixedArr;
}
fn1(num1, num2);
// 法二
function fn2(arr1, arr2) {
return arr1.map(item => {
if (arr2.includes(item)) {
return item
}
})
}
const res2 = fn2(num1, num2);
console.log(res2);
// 法三
function fn3(arr1, arr2) {
return arr1.filter(v => arr2.includes(v))
}
const res3 = fn3(num1, num2);
console.log(res3);
// 法四 set数据结构
function fn4(arr1, arr2) {
// 交集
let intersect = new Set([...arr1].filter(item => arr2.has(item)));
console.log('intersect', intersect)
return intersect;
}
let x = new Set([1, 2, 3]);
let y = new Set([4, 3, 2]);
fn4(x, y);
求2个数组的并集
let num3 = [1, 2, 3, 4];
let num4 = [4, 5, 6, 7, 3];
console.log(new Set([...num3, ...num4]));
求2个数组的差集
let num5 = [1, 2, 3, 4];
let num6 = [4, 5, 6, 7, 3];
// 求数组1相对于数组2的差集 [5,6,7]
function getDifference(arr1, arr2) {
return arr2.filter(item => !arr1.includes(item))
}
const res6 = getDifference(num5, num6);
console.log('res6', res6);
7.数组扁平化
const arr = [1, [2, 3], [4, [5, [6, 7]]]]
// 法一
const res1 = arr.flat(Infinity);
console.log('res1', res1);
// 法二:函数递归
const getFlatArr = (arr) => {
let flatArr = []; //注意这个要定义在函数里面,否则就不是一个纯函数了。
// console.log('flatArr-inner-真实的值', JSON.stringify(flatArr));
// console.log('flatArr-inner-被改变后的值', flatArr);
for (const item of arr) {
if (Array.isArray(item)) {
const innerFlatArr = getFlatArr(item)
// flatArr = flatArr.concat(innerFlatArr)
flatArr = [...flatArr, ...innerFlatArr]
} else {
flatArr.push(item)
}
}
return flatArr;
}
const res2 = getFlatArr(arr);
console.log('res2', res2);
// 法三:reduce(实际也是递归)
const getFlatArr3 = (arr) => {
return arr.reduce((pre, cur) => {
return pre.concat(Array.isArray(cur) ? getFlatArr3(cur) : cur)
}, [])
}
const res3 = getFlatArr3(arr);
console.log('res3', res3);
8.数组去重
const arr = [1, 2, 2, 3, 3, 3]
// 法一:
console.log([...new Set(arr)]);
console.log(Array.from(new Set(arr)));
// 法二
const quchong = (arr) => {
const newArr = [];
for (const item of arr) {
if (!newArr.includes(item)) {
newArr.push(item);
}
}
return newArr
}
const res = quchong(arr);
console.log('res', res);
9.数组的扁平化和tree化
需求1:把tree数据结构扁平化,即取出children的值放在最外面的数组里面,children里面如果又有children则继续取,递归
const treeSource = [
{
id: "1",
name: '部门1',
pid: "0",
children: [
{
id: "1-1", name: '部门1的子部门1-1', pid: "1", children: [
{
id: "1-1-1", name: '部门1-1的子部门1-1-1', pid: "1-1",
},
{
id: "1-1-2", name: '部门1-1的子部门1-1-2', pid: "1-1",
}]
},
{ id: "1-2", name: '部门1的子部门1-2', pid: "1" },
]
},
{
id: "2",
name: '部门2',
pid: "0",
children: [
{
id: "2-1", name: '部门2的子部门2-1', pid: "2", children: [
{
id: "2-1-1", name: '部门2-1的子部门2-1-1', pid: "2-1",
}
]
}
]
},
{
id: "3",
name: '部门3',
pid: "0",
children: []
}
]
const getFlatTarget = (treeSource) => {
let flatTargetArr = []
for (const item of treeSource) {
const { children, ...i } = item
if (children && children.length > 0) {
// flatTargetArr = flatTargetArr.concat(getFlatTarget(children))
flatTargetArr = [...flatTargetArr, ...getFlatTarget(children)]
}
flatTargetArr.push(i)
}
return flatTargetArr;
}
const flatTargetArr = getFlatTarget(treeSource);
console.log('flatTargetArr', flatTargetArr)
需求2:把扁平数据结构tree化,即pid=0是顶级,pid =1,parentId为1,通过pid找到对应的id项,放入children里面
const sourceTarget = [
{ id: "1", name: '部门1', pid: "0" },
{ id: "1-1", name: '部门1的子部门1-1', pid: "1" },
{ id: "1-1-1", name: '部门1-1的子部门1-1-1', pid: "1-1" },
{ id: "1-1-2", name: '部门1-1的子部门1-1-2', pid: "1-1" },
{ id: "1-2", name: '部门1的子部门1-2', pid: "1" },
{ id: "2", name: '部门2', pid: "0" },
{ id: "2-1", name: '部门2的子部门2-1', pid: "2" },
{ id: "2-1-1", name: '部门2-1的子部门2-1-1', pid: "2-1" },
{ id: "3", name: '部门3', pid: "0" }
]
// 法一
const getTreeData1 = (sourceTarget) => {
const itemMap = {}
const treeData = [];//用于存放tree化后的数组
for (const item of sourceTarget) {
item.children = [];
itemMap[item.id] = item //第一步为啥需要将数据这样放一遍,方便Object.keys(obj)遍历
}
for (const key in itemMap) {
let item = itemMap[key]; //源数据的每一项,加了一个children属性
if (!Object.keys(itemMap).includes(item.pid)) {
//通过pid没有找到对应id的item项则为顶级
treeData.push(item)
} else {
// 通过pid找到了对应的id的item项,则把该项放入到父级item的children中
const parentItem = itemMap[item.pid];
parentItem.children.push(item)
}
}
// sourceTarget.forEach(item => {
// itemMap[item.id] = item
// item.children = [];
// })
// console.log(itemMap)
// sourceTarget.forEach(item => {
// if (Object.keys(itemMap).includes(item.pid)) {
// itemMap[item.pid].children.push(item)
// } else {
// treeData.push(item)
// }
// })
return treeData;
}
const res1 = getTreeData1(sourceTarget);
console.log('res1', res1);
//法二
const getTreeData2 = (sourceTarget) => {
const treeData = [];
const itemMap = {};
for (const item of sourceTarget) {
itemMap[item.id] = {
...item,
children: []
}
}
for (const item of sourceTarget) {
const id = item.id;
const pid = item.pid;
const treeItem = itemMap[id];//把树的父级存下
if (pid === '0') { //顶层
treeData.push(treeItem)
} else { //非顶层
// if (!itemMap[pid]) { //如果某项没有pid
// itemMap[pid] = {
// children: [],
// }
// }
const parentItem = itemMap[item.pid];
parentItem.children.push(item)
}
}
return treeData;
}
const treeData = getTreeData2(sourceTarget);
console.log('treeData', treeData);
10.无重复字符的最长子串 (难)
const str = 'abcdaa123vopsad'
var lengthOfLongestSubstring = function (s) {
let l = 0;
let res = 0;
const map = new Map();
for (let r = 0; r < s.length; r++) {
if (map.has(s[r]) && map.get(s[r]) >= l) { // 注意 abbcdea 这种情况
l = map.get(s[r]) + 1;
}
res = Math.max(res, r - l + 1); //更新最长子串
map.set(s[r], r);
}
return res;
};
const res = lengthOfLongestSubstring(str);
console.log('str', str);