1.实现一个简单的模板
实现一个render(template,context)方法,将template中的占位符用context填充
示例
var template = '{{name}}很帅,今年{{age}}岁'
var context = {name:'Tom',age:17};
//输入 template context
// 输出 Tom很帅,今年17岁
如下:
①先试用正则匹配到所有的{{name}},{{age}};
②利用str.splace(RegExp,function),其中第二个参数的函数返回值将替换掉一个参数匹配的结果;
var template = '{{name}}很帅,今年{{age}}岁'
var context = { name: 'Tom', age: 17 };
function render(template, context){
return template.replace(/{{(.*?)}}/g,(x,y)=>{
return context[y];
})
}
let s =render(template, context);
console.dir(s)
2.将数组扁平化去并除其中重复部分数据,最终得到一个升序且不重复的数组
var arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10];
第一种:ES6中Array.prototype.flat
/*
- new Set 去重
- arr.flat扁平化
- sort排序
*/
let x = Array.from(new Set(arr.flat(Infinity))).sort((a, b) => a - b);
let x = Array.from(new Set(arr.toString().split(','))).sort((a,b)=>a-b).map(x=>Number(x));
console.log(x) //=>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
第二种:JSON.stringify
/*
+ JSON.stringify(arr) => 把原数组转换成字符串形式的;
+ replace(/(\[|\])/g,'') =>替换 字符串中的[]
*/
arr = JSON.stringify(arr).replace(/(\[|\])/g,'').split(',').map(item=>{
return Number(item);
});
第三种 : some
//find和some的区别:some返回的是boolean,find找到符合规则的,返回当前这一项,没找到符合规则的,返回undefined
//=>Array.isArray([val]):检测某个值是否为数组类型(挺准的)
=>基于数组的some方法进行判断检测:验证数组中的某一项有没有符合函数中提供的规则的
while (arr.some(item => Array.isArray(item))) {
arr = [].concat(...arr);
}
第四种 : 递归处理
~ function () {
function myFlat() {
let result = [],
_this = this;
//=>循环ARR中的每一项,把不是数组的存储到新数组中
let fn = (arr) => {
for (let i = 0 i < arr.length; i++) {
let item = arr[i];
if (Array.isArray(item)) {
fn(item);
continue;
}
result.push(item);
}
};
fn(_this);
return result;
}
Array.prototype.myFlat = myFlat;
}();
arr = arr.myFlat();
3.如何实现一个 new?
创建一个空对象,它的__proto__指向构造函数原型;
使其this指向新创建的对象;
return若为非基本类型值,则返回这个值,否则返回新创建的对象;
/*补充一个知识点:
=>Object.create([AA对象]):创建一个空对象obj,并且让空对象obj作为AA对象所属构造函数的实例(obj.__proto__=AA)
*/
function _new(Fn,...arg){
let obj = Object.create(Fn.prototype);
let result = Fn.call(obj,...arg);
return typeOf result==='object'? result : obj;
}
let sanmao = _new(Dog, '三毛');
4.合并数组并重新排序
let ary1 = ['A1', 'A2', 'B1', 'B2', 'C1', 'C2', 'D1', 'D2'];
let ary2 = ['A', 'B', 'C', 'D'];
//=>合并后的数组为:['A1', 'A2', 'A', 'B1', 'B2', 'B', 'C1', 'C2', 'C', 'D1', 'D2', 'D'];
第一种
拼接数组,并且利用localeCompare进行排序
ary2 = ary2.map(item=>item+'z');
arr=ary1.concat(ary2).sort((a,b)=>a.localeCompare(b)).map(item=>item.replace('z',''));
第二种
// 判断ary1是否包括ary2每一项,>如果包含就记录一下当前这一项的索引位置(后面还有包含的会重新记录这个值)
// 把当前ITEM2这一项插入到ARY1中N的后面
let n;
for (let i = 0; i < ary2.length; i++) {
let item2 = ary2[i];
for (let k = 0; k < ary1.length; k++) {
let item1 = ary1[k];
if (item1.includes(item2)) {
n = k;
}
}
ary1.splice(n + 1, 0, item2);
}
console.log(ary1);
5.改造下面的代码,使之输出0 - 9,写出你能想到的所有解法
for (var i = 0; i< 10; i++){
setTimeout(() => {
console.log(i);
}, 1000)
}
1.利用let块级作用域
for (let i = 0; i< 10; i++){
setTimeout(() => {
console.log(i);
}, 1000)
}
2.利用闭包保存机制
for (var i = 0; i < 10; i++) {
(function (i) {
setTimeout(() => {
console.log(i);
}, 1000)
})(i)
}
//或着这种写法
for (var i = 0; i < 10; i++) {
setTimeout((i => () => console.log(i))(i), 1000);
}
//setTimeout第三个参数,会作为回调函数的第一个参数传入
for (var i = 0; i < 10; i++) {
setTimeout(i => {
console.log(i);
}, 1000,i)
}
3.bind
=>可以基于bind的预先处理机制:在循环的时候就把每次执行函数需要输出的结果,预先传给函数即可
var fn = function (i) {
console.log(i);
};
for (var i = 0; i < 10; i++) {
setTimeout(fn.bind(null, i), 1000);
}
6.使用迭代的方式实现 flatten 函数。
let arr = [1, 2, [3, 4, 5, [6, 7], 8], 9, 10, [11, [12, 13]]]
const flatten = function (arr) {
while (arr.some(item => Array.isArray(item))) {
arr = [].concat(...arr)
}
return arr
}
console.log(flatten(arr))
7.下面代码中 a 在什么情况下会打印 1?
var a = ?;
if(a == 1 && a == 2 && a == 3){
console.log(1);
}
复习下 ==
== 相对相等,如果左右两边数据类型不一样,则先转换为相同的数据类型,然后在进行比较
- {}=={} 两个对象进行比较,比较的是堆内存的地址
- null==undefined 相等的 / null===undefined 不相等
- NaN==NaN 不相等 NaN和谁都不相等
- [12]=="12" 对象和字符串比较,是把对象toString()转换为字符串后再进行比较的
- 剩余所有情况在进行比较的时候,都是转换为数字(前提数据类型不一样)
对象转数字:先转换为字符串,然后再转换为数字字符串转数字:只要出现一个非数字字符,结果就是NaN布尔转数字:true->1 false->0null转数字0undefined转数字NaN
=======第一种========
// =>对象和数字比较:先把对象.toString()变为字符串,然后再转换为数字
a.toString(); //=>此时调取的就不再是Object.prototype.toString了,调取的是自己私有的
var a = {
n: 0,
toString() {
return ++this.n;
}
}
=========第二种========
//=>shift:删除数组第一项,把删除的内容返回,原有数组改变
// 调取toString === a.shift;
let a = [1, 2, 3];
a.toString = a.shift;
=========第三种=========
// ES6中新增加的一些方法
// Object.defineProperty属性,执行window.a的时候,会先执行get这个函数,所以在get这个函数编写代码即可;
Object.defineProperty(window, 'a', {
get: function () {
//=>this:window.a => undefined;
this.value ? this.value++ : this.value = 1;
return this.value;
}
});
8:实现一个 sleep 函数
比如 sleep(1000) 意味着等待1000毫秒,可从 Promise、Generator、Async/Await 等角度实现
9.实现 (5).add(3).minus(2) ,使其输出结果为:6
例: 5 + 3 - 2,结果为 6
// 每次方法执行完,都要返回NUMBER这个类的实例,这样才可以继续调取NUMBER类原型中的方法(链式写法);
(function () {
function check(n) {
n = Number(n);
return isNaN(n) ? 0 : n;
}
function add(n) {
n = check(n);
return this + n;
}
function minus(n) {
check(n)
return this - n;
}
['add', 'minus'].forEach(item => {
Number.prototype[item] = eval(item);
})
})()
let res = (5).add(3).minus(2);
console.log(res); // => 6
10.冒泡排序如何实现,时间复杂度是多少, 还可以如何改进?
function bubbleSort(arr) {
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
const temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
console.log(arr);
}
// 改进冒泡排序
function bubbleSort1(arr) {
let i = arr.length - 1;
while (i > 0) {
let pos = 0;
for (let j = 0; j < i; j++) {
if (arr[j] > arr[j + 1]) {
pos = j;
const temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
i = pos;
}
console.log(arr);
}
11.某公司 1 到 12 月份的销售额存在一个对象里面
如下:{1:222, 2:123, 5:888},请把数据处理为如下结构:[222, 123, null, null, 888, null, null, null, null, null, null, null]。
let obj = { 1: 222, 2: 123, 5: 888 };
=======第一种======
const result = Array.from({ length: 12 }).map((_, index) => obj[index + 1] || null);
// =>或着
let ary = new Array(12).fill(null).map((item,index) => {
return obj[index+1] || item;
});
console.log(ary) // [222, 123, null, null, 888, null, null, null, null, null, null, null];
========第二种========
let obj = {
1: 222,
2: 123,
5: 888
};
obj.length = 13;
let ary = Array.from(obj).slice(1).map(item => {
return typeof item === "undefined" ? null : item;
})
console.log(ary) // [222, 123, null, null, 888, null, null, null, null, null, null, null];
=======第三种 =====
let obj = {
1: 222,
2: 123,
5: 888
};
// =>Object.keys(obj):获取obj中所有的属性名,以数组的方式返回
let arr = Object.keys(obj);
console.log(arr); //["1", "2", "5"]
let ary = new Array(12).fill(null);
arr.forEach(item =>{
ary[item - 1] = obj[item];
})
console.log(ary) // [222, 123, null, null, 888, null, null, null, null, null, null, null]
12.要求设计 LazyMan 类,实现以下功能
LazyMan('Tony');
// Hi I am Tony
LazyMan('Tony').sleep(10).eat('lunch');
// Hi I am Tony
// 等待了10秒...
// I am eating lunch
LazyMan('Tony').eat('lunch').sleep(10).eat('dinner');
// Hi I am Tony
// I am eating lunch
// 等待了10秒...
// I am eating diner
LazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleep(10).eat('junk food');
// Hi I am Tony
// 等待了5秒...
// I am eating lunch
// I am eating dinner
// 等待了10秒...
// I am eating junk food
如下
class LazyManClass {
constructor(name) {
this.taskList = [];
this.name = name;
console.log(`Hi I am ${this.name}`);
setTimeout(() => {
this.next();
}, 0);
}
eat (name) {
var that = this;
var fn = (function (n) {
return function () {
console.log(`I am eating ${n}`)
that.next();
}
})(name);
this.taskList.push(fn);
return this;
}
sleepFirst (time) {
var that = this;
var fn = (function (t) {
return function () {
setTimeout(() => {
console.log(`等待了${t}秒...`)
that.next();
}, t * 1000);
}
})(time);
this.taskList.unshift(fn);
return this;
}
sleep (time) {
var that = this
var fn = (function (t) {
return function () {
setTimeout(() => {
console.log(`等待了${t}秒...`)
that.next();
}, t * 1000);
}
})(time);
this.taskList.push(fn);
return this;
}
next () {
var fn = this.taskList.shift();
fn && fn();
}
}
function LazyMan(name) {
return new LazyManClass(name);
}
LazyMan('Tony').eat('lunch').eat('dinner').sleepFirst(5).sleep(4).eat('junk food');
13.给定两个数组,写一个方法来计算它们的交集。
例如:
let nums1 = [12, 23, 34, 23, 45, 34,24, 25, 46, 35]; let nums2 = [10, 35, 24, 23, 36, 47, 56]; //=> 输出结果: [23, 24, 35]
// 第一种使用new Set 的has
// + has(value):判断集合中是否存在 value
let set1 = [12, 23, 34, 23, 45, 34, 25, 46, 35]
let set2 = new Set([10, 35, 24, 23, 36, 47, 56]);
let intersect = Array.from(new Set([...set1].filter(value => set2.has(value))))
=======第二种======
let arr = [];
nums1.forEach((item, index) => {
let n = nums2.indexOf(item);
if (n >= 0) {
arr.push(item);
nums1.splice(index, 1);
nums1.splice(n, 1);
}
});
console.log(arr);
==========第三种==========
let arr = [];
for (let i = 0; i < nums1.length; i++) {
let item1 = nums1[i];
for (let k = 0; k < nums2.length; k++) {
let item2 = nums2[k];
if (item1 === item2) {
arr.push(item1);
break;
}
}
}
console.log(arr);
14.随机生成一个长度为 10 的整数类型的数组,例如 [2, 10, 3, 4, 5, 11, 10, 11, 20],将其排列成一个新数组,要求新数组形式如下,例如 [[2, 3, 4, 5], [10, 11], [20]]。
15.如何把一个字符串的大小写取反(大写变小写小写变大写),例如 ’AbC' 变成 'aBc'
let str = 'JinTianTIanQiHenhao';
str = str.replace(/[a-zA-Z]/g, content => {
//content:每一次正则匹配到的结果;
// 验证是否大写字母,统一转换成大写,再跟之前的字母对比,如果一样,说明之前也是大写;
// 在ASCII 表中找到大写字母的取值范围进行判断(65-90);
return content.toUpperCase() === content ? content.toLowerCase() : content.toUpperCase();
});
console.log(str) // =>'jINtIANtiANqIhENHAO'
16.实现一个字符串匹配算法,从字符串 S 中,查找是否存在字符串 T,若存在返回所在位置,不存在返回-1!(如果不能基于indexOf/includes等内置的方法,你会如何处理呢?)
/*
S: 查找S中T是否存在
pramas: [T] =>需要查找的字符串内容;
return:存在返回其索引,不存在返回-1;
*/
// 循环原始字符串中每一项,让每一项从当前位置向后截取 T.length个字符,
// 然后和T进行比较,如果不一样继续循环;如果一样返回当前索引即可;
// THIS:S =>原字符串;
// pramas: [T]=> 需查找的字符串;
// return: 匹配完整字符串开始的索引;
~function () {
function myIndexOf(T) {
let lenT = T.length,
lenS = S.length,
res = -1;
if (lenS < lenT) return null;
for (let i = 0; i < lenS - lenT; i++) {
if(this.substr(i, lenT) === T){
res = i;
break; // 为了避免出现多个符合,找最后一个,让其找到一个就结束;
};
};
return res;
};
String.prototype.myIndexOf = myIndexOf;
}();
let S = 'jingerzitiantianqihenhao',
T = 'tian';
let res = S.myIndexOf(T);
console.log(res);
=========第二种=========
**使用正则匹配**
~function () {
function myIndexOf(T) {
let reg = new RegExp(T),
res = reg.exec(this);
return res === null ? -1 : res.index;
}
String.prototype.myIndexOf = myIndexOf;
}();
let S = 'jingerzitianqihenhao',
T = 'tian';
let res = S.myIndexOf(T);
console.log(res);
17.给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
/*
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数
输入: [1, 2, 3, 4, 5, 6, 7] 和 k = 3
输出: [5, 6, 7, 1, 2, 3, 4]
解释:
向右旋转 1 步: [7, 1, 2, 3, 4, 5, 6]
向右旋转 2 步: [6, 7, 1, 2, 3, 4, 5]
向右旋转 3 步: [5, 6, 7, 1, 2, 3, 4]
输入: [-1, -100, 3, 99] 和 k = 2
输出: [3, 99, -1, -100]
解释:
向右旋转 1 步: [99, -1, -100, 3]
[3, 99, -1, -100]
*/
==== 第一种========
let arr = [1, 2, 3, 4, 5, 6, 7];
function change(k) {
if (k < 0 && k === this.length) return;
if (k > this.length) return k = k % this.length;
return this.slice(-k).concat(this.slice(0, this.length - k));
// return [...this.splice(this.length-k),...this];
}
Array.prototype.change = change;
let ary = arr.change(3);
console.log(ary);
=========第二种========
function change(k) {
//=>参数处理
if (k < 0 || k === 0 || k === this.length) return this;
if (k > this.length) k = k % this.length;
// for (let i = 0; i < k; i++) {
// this.unshift(this.pop());
// }
new Array(k).fill('').forEach(() => this.unshift(this.pop()));
return this;
}
Array.prototype.change = change;
let ary = arr.change(3);
console.log(ary); // [5, 6, 7, 1, 2, 3, 4]
18.打印出 1 - 10000 之间的所有对称数
19.给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:
必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数
function zeroMove(arr) {
let len = arr.length;
let j = 0;
for (let i = 0; i < len; i++) {
if (arr[i] === 0) {
arr.push(0);
arr.splice(i, 1);
i--;
j++;
}
}
return arr;
}
let x = zeroMove([0, 1, 0, 3, 12]);
20.请实现一个 add 函数,满足以下功能
add(1); // 1
add(1)(2); // 3
add(1)(2)(3);// 6
add(1)(2, 3); // 6
add(1, 2)(3); // 6
add(1, 2, 3); // 6
function currying(fn, length) {
length = length || fn.length;
return function (...args) {
if (args.length >= length) {
return fn(...args);
}
return currying(fn.bind(null, ...args), length - args.length);
}
}
let add = currying((...arg) => eval(arg.join('+')), 5);
console.log(add(1, 2, 3, 4, 5));
console.log(add(1, 2)(3, 4, 5));
console.log(add(1, 2)(3, 4)(5));
console.log(add(1, 2)(3)(4)(5));
console.log(add(1)(2)(3)(4)(5));
21.两数之和
给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。
你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
简单直接
let nums = [2, 7, 11, 15], target = 15
function twoSum(nums, target) {
for (let i = 0; i < nums.length; i++) {
for (let k = 0; k < nums.length; k++) {
if (i !== k && nums[i] + nums[k] === target) {
return [i, k];
}
}
}
return '沒有找到哦~';
}
console.log(twoSum(nums, target))
22.在输入框中如何判断输入的是一个正确的网址,例如:用户输入一个字符串,验证是否符合URL网址的格式
=>首先我们需要了解URL的格式
1.协议:// http/https/ftp
2.域名
www.sina.cn
sina.cn
kbs.sports.qq.com
kbs.sports.qq.com.cn
3.请求路径
/
/index.html
/stu/index.html
/stu/
4.问号传参
?xxx=xxx&xxx=xxx
5.哈希值
// #xxx
*/
let str = "https://www.sina.com.cn";
let reg = /^(?:(http|https|ftp):\/\/)?((?:[\w-]+\.)+[a-z0-9]+)((?:\/[^/?#]*)+)?(\?[^#]+)?(#.+)?$/i;
console.log(reg.exec(str));
23.实现 convert 方法,把原始 list 转换成树形结构,要求尽可能降低时间复杂度
以下数据结构中,id 代表部门编号,name 是部门名称,parentId 是父部门编号,为 0 代表一级部门,现在要求实现一个 convert 方法,把原始 list 转换成树形结构,parentId 为多少就挂载在该 id 的属性 children 数组下,结构如下:
// 原始 list 如下
let list =[
{id:1,name:'部门A',parentId:0},
{id:2,name:'部门B',parentId:0},
{id:3,name:'部门C',parentId:1},
{id:4,name:'部门D',parentId:1},
{id:5,name:'部门E',parentId:2},
{id:6,name:'部门F',parentId:3},
{id:7,name:'部门G',parentId:2},
{id:8,name:'部门H',parentId:4}
];
const result = convert(list, ...);
// 转换后的结果如下
let result = [
{
id: 1,
name: '部门A',
parentId: 0,
children: [
{
id: 3,
name: '部门C',
parentId: 1,
children: [
{
id: 6,
name: '部门F',
parentId: 3
}, {
id: 16,
name: '部门L',
parentId: 3
}
]
},
{
id: 4,
name: '部门D',
parentId: 1,
children: [
{
id: 8,
name: '部门H',
parentId: 4
}
]
}
]
},
···
];
使用reduce
function covert(list) {
const res = [];
const map = list.reduce((res, v) => (res[v.id] = v, res), {})
for (let item of list) {
if (item.parentId === 0) {
res.push(item);
continue;
}
if (item.parentId in map) {
let parent = map[item.parentId];
parent.children = parent.children || [];
parent.children.push(item);
}
};
return res;
}
console.log(covert(list));
24.实现模糊搜索结果的关键词高亮显示
25.用 JavaScript 写一个函数,输入 int 型,返回整数逆序后的字符串。
如:输入整型 1234,返回字符串“4321”。要求必须使用递归函数调用,不能用全局变量,输入函数必须只有一个参数传入,必须返回字符串。
26.请写出一个函数,完成以下功能输入
输入 1,2,3,5,7,8,10
输出 1~3,5,7~8,10
let num = [1, 2, 3, 5, 7, 8, 10];
/*
* 每一项+1,是否与后一项相同,若不相同,则返回范围值(说明已经不连续了);
* 把不连续值,继续赋值,重新进行对比;
*/
function str(mum) {
var result = [],
temp = num[0];
num.forEach((item, index) => {
if (item + 1 !== num[index + 1]) {
if (temp !== item) {
result.push(`{temp}~${item}`)
} else {
result.push(`${item}`);
}
};
temp = num[index + 1];
})
}
str(num);
27.
var entry = {
'a.b.c.dd': 'abcdd',
'a.d.xx': 'adxx',
'a.e': 'ae'
}
// 转换成:
var output = {
a: {
b: {
c: {
dd:
'abcdd'
}
},
d:{
xx:'adxx'
},
e:'ae'
}
}
28.找出字符串中连续出现最多的字符和个数
let str = "jintiantianqihaodehenneshibushi";
=====第一种====
+ 循环str,并且把str每项作为属性存入obj,默认属性值为1;
+ 循环中判断str中的每一项中是否为undefined,非undefined,说明已经存在原基础上累加;
let obj = {};
[].forEach.call(str, char => {
if (typeof obj[char] !== "undefined") {
obj[char]++;
return;
}
obj[char] = 1;
});
let max = 1,
res = [];
for (let key in obj) {
let item = obj[key];
item > max ? max = item : null;
}
for (let key in obj) {
let item = obj[key];
if (item === max) {
res.push(key);
}
}
console.log(`出现次数最多的字符是:${res},出现了${max}次`);
============第二种=============
+ 基于localeCompare对字符串进行排序;
+ 利用正则匹配多个字符,并借用length进行排序
str = str.split('').sort((a, b) => a.localeCompare(b)).join(''); //=>"aaabdeeehhhhiiiiiijnnnnnoqssttu"
let reg = /([a-zA-Z])\1+/g;
let ary = str.match(reg); //=> ["aaa", "eee", "hhhh", "iiiiii", "nnnnn", "ss", "tt"]
ary.sort((a, b) => b.length - a.length); //=>["iiiiii", "nnnnn", "hhhh", "aaa", "eee", "ss", "tt"]
let max = ary[0].length,
res = [ary[0].substr(0, 1)];
// 考虑可能会存在多个length一样的
for (let i = 1; i < ary.length; i++) {
let item = ary[i];
if (item.length < max) {
break;
}
res.push(item.substr(0, 1));
}
console.log(`出现次数最多的字符是:${res},出现了${max}次`);
========第三种=======
let max = 0,
res = [],
flag = false;
str = str.split('').sort((a, b) => a.localeCompare(b)).join('');
for (let i = str.length; i > 0; i--) {
let reg = new RegExp("([a-zA-Z])\\1{" + (i - 1) + "}", "g");
str.replace(reg, (content, $1) => {
res.push($1);
max = i;
flag = true;
});
if (flag) break;
}
console.log(`出现次数最多的字符:${res},出现了${max}次`);
29.获取数组中的最大值和最小值
let ary = [12, 24, 13, 8, 35, 15];
=======sort========
ary.sort(function (a, b) {
return a - b;
});
let min = ary[0];
let max = ary[ary.length - 1];
console.log(min, max)
=====Math.max/Math.min===
=>Math.max/min要求我们传递的数据是一项项传递进来,获取一堆数中的最大最小,而不是获取一个数组中的最大最小
let min = Math.min(...ary);
======假设法=========
let max = ary[0];
for (let i = 1; i < ary.length; i++) {
let item = ary[i];
item > max ? max = item : null;
}
console.log(max); //=>35
30. 时间字符串的格式化处理
~ function () {
/*
* formatTime:时间字符串的格式化处理
* @params
* templete:[string] 我们最后期望获取日期格式的模板
* 模板规则:{0}->年 {1~5}->月日时分秒
* @return
* [string]格式化后的时间字符串
* by LYR on 2019/08/13
*/
function formatTime(templete = "{0}年{1}月{2}日 {3}时{4}分{5}秒") {
let timeAry = this.match(/\d+/g);
return templete.replace(/\{(\d+)\}/g, (...[, $1]) => {
let time = timeAry[$1] || "00";
return time.length < 2 ? "0" + time : time;
});
}
/* 扩展到内置类String.prototype上 */
["formatTime"].forEach(item => {
String.prototype[item] = eval(item);
});
}();
let time = "2019-8-13 16:51:3";
console.log(time.formatTime());
console.log(time.formatTime("{0}年{1}月{2}日"));
console.log(time.formatTime("{1}-{2} {3}:{4}"));
time = "2019/8/13";
console.log(time.formatTime());
console.log(time.formatTime("{0}年{1}月{2}日"));
console.log(time.formatTime("{1}-{2} {3}:{4}"));
31. 获取URL地址问号和面的参数信息(可能也包含HASH值)
/*
* queryURLParams:获取URL地址问号和面的参数信息(可能也包含HASH值)
* @params
* @return
* [object]把所有问号参数信息以键值对的方式存储起来并且返回
* by LYR on 2019/01/01
*/
function queryURLParams() {
let obj = {};
this.replace(/([^?=&#]+)=([^?=&#]+)/g, (...[, $1, $2]) => obj[$1] = $2);
this.replace(/#([^?=&#]+)/g, (...[, $1]) => obj['HASH'] = $1);
return obj;
}
/* 扩展到内置类String.prototype上 */
["formatTime", "queryURLParams"].forEach(item => {
String.prototype[item] = eval(item);
});
}();
let url = "http://www.lalala.cn/?lx=1&from=wx#video";
console.log(url.queryURLParams());
//=>{lx:1,from:'wx',HASH:'video'}
32. 千分符
/*
* millimeter:实现大数字的千分符处理
* @params
* @return
* [string]千分符后的字符串
* by LYR on 2019/08/13
*/
function millimeter() {
return this.replace(/\d{1,3}(?=(\d{3})+$)/g, content => content + ',');
}
/* 扩展到内置类String.prototype上 */
["formatTime", "queryURLParams", "millimeter"].forEach(item => {
String.prototype[item] = eval(item);
});
}();
let num = "15628954"; //=>"15,628,954" 千分符
console.log(num.millimeter());
num = "112345678256874"; //=>"12,345,678,256,874"
console.log(num.millimeter());
// 把字符串倒过来加
/* num = num.split('').reverse().join('');
for (let i = 2; i < num.length - 1; i += 4) {
let prev = num.substring(0, i + 1),
next = num.substring(i + 1);
num = prev + "," + next;
}
num = num.split('').reverse().join('');
console.log(num); */
33. indexOf
let indexOf = (S, T) => {
if (S.length < T.length) return -1;
for (let i = 0; i < S.length - T.length ; i++) {
if (S.substr(i, T.length) === T) return i;
}
return -1;
};
34. 编写一条正则,用来验证此规则:一个6~16位的字符串,必须同时包含有大小写字母和数字
let reg = /(?!^[a-zA-Z]+$)(?!^[A-Z0-9]+$)(?!^[a-z0-9]+$)^[a-zA-Z0-9]{6,16}$/;
35. 完成如下需求
/* 实现一个$attr(name,value)遍历
* 属性为name
* 值为value的元素集合
*
* 例如下面示例:
*/
<div id="AA" class="box clearfix"></div>
<div myIn="1"></div>
<div class="content box"></div>
<div name="BB"></div>
<div></div>
<div id="AA"></div>
<div myIn="1" class="clearfix"></div>
<div class="box"></div>
<div class="box banner"></div>
<div myIn="2"></div>
<div name="BB"></div>
function $attr(property, value) {
let ele = document.getElementsByTagName('*'), // 获取到元素集合的类数组;
arr = [];
ele = Array.from(ele);
ele.forEach(item => {
let itemValue = item.getAttribute(property);
// 因为Class比较特殊,可以有多个名字,可能多个类名中包含其中的,
// 但是整体类名不会检测出来,所以需要特殊处理;
if (property === 'class') {
new RegExp("\\b" + value + "\\b").test(itemValue) ? arr.push(item) : null;
};
if (itemValue === value) {
arr.push(item);
};
});
return arr;
};
let ary = $attr('class', 'box'); //=>获取页面中所有class为box的元素
console.log(ary)
36. 数组重组 (将name值相同的合并,并去除age的属性)
// 数组重组 (将name值相同的合并,并去除age的属性)
let ary = [
{name:1,age:2,number:1,son:'son1'},
{name:2,age:23,number:2,son:'son2'},
{name:2,age:22,number:3,son:'son3'},
{name:1,age:12,number:4,son:'son4'},
{name:1,age:42,number:5,son:'son5'}
]
fn(ary) // 结果为
[
{
"name":1,
"list":[{"number":1,"son":"son1"},{"number":4,"son":"son4"},{"number":5,"son":"son5"}]
},
{
"name":2,
"list":[{"number":2,"son":"son2"},{"number":3,"son":"son3"}]
}
]
如下:
function fn(ary){
let arr = [];
ary.forEach(item=>{
let bol = arr.some(val=>{
if(val.name===item.name){
let obj = {};
Object.keys(item).forEach(v=>{
if(v!='name'&&v!='age'){
obj[v] = item[v]
}
})
val.list.push(obj);
return true
}
})
if(!bol){
let obj = {};
Object.keys(item).forEach(v=>{
if(v!='name'&&v!='age'){
obj[v] = item[v]
}
})
arr.push({name:item.name,list:[obj]});
}
})
return arr;
}
fn(ary)