flat和flatMap
flat
- 数组扁平化,根据参数的数值多大深度,原数组不改变,返回一个新的扁平化数组
var arr = [[1,2,3],[4,5,[6,7,8,9,[10,11,12]]]]
var arr1 = arr.flat(5)
console.log(arr1) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
// flat 重构
function arrayFlat(array, deep = 1, arr = [], currentLv = 0) {
if (!array || array.constructor !== Array) throw new TypeError(array + "not is Array!");
for (var i = 0; i < array.length; i++) {
// 元素不是数组的,直接添加在新数组中
if (!array[i] || array[i].constructor !== Array) {
arr[arr.length] = array[i];
} else {
// 元素是数组的,如果最大深度大于当前深度,递归
if (deep > currentLv) {
arrayFlat(array[i], deep, arr, currentLv + 1);
} else {
// 否则直接将当前元素放在新数组中
arr[arr.length] = array[i];
}
}
}
return arr;
}
flatMap
- 扁平化映射,一般用于处理二维数组扁平化
- arr.flatMap(回调函数,thisArg)
- 原数组不改变,返回一个扁平化的数组
// 案例
var arr = [1, 2, 3, [4, 5, 6], 7, 8, [10, 11, 12], [95, 97, 454, 1]]
var arr1 = arr.flatMap(function (item) {
return item
})
console.log(arr1); // [1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 95, 97, 454, 1]
// 重构
function arrayFlatMap(array, callback, thisArg) {
if (!array || array.constructor !== Array) throw new TypeError(array + "not is Array!");
if (typeof callback !== "function") throw new TypeError(callback + "is not Function!");
var arr = []
for (var i = 0; i < array.length; i++) {
var item = callback(array[i], i, array);
if (!item || item.constructor !== Array) {
arr[arr.length] = item;
} else {
for (var j = 0; j < item.length; j++) {
arr[arr.length] = item[j];
}
}
}
return arr;
}
join
- 不改变原数组,使用连接符将数组中元素转为字符串连接在一起,返回连接好的字符串
- arr.join(连接符)
// 举例
var arr = [1, 2, 3, 4, 5, 6]
console.log(arr.join(' # ')); // 1 # 2 # 3 # 4 # 5 # 6
console.log(arr.join(' ')); // 1 2 3 4 5 6
console.log(arr.join()); // 1,2,3,4,5,6
// 重构
function arrayJoin(array, separator = ",") {
if (!array || array.constructor !== Array) throw new TypeError(array + "not is Array!");
separator = String(separator);
var str = "";
for (var i = 0; i < array.length; i++) {
if (i < array.length - 1) str += array[i] + separator;
else str += array[i];
}
return str;
}
reverse
- 数组的反转
- 修改原数组,并且返回这个数组
var arr = [1, 468, 13, 19, 46, 44, 38, 95]
console.log(arr.reverse()); // [95, 38, 44, 46, 19, 13, 468, 1]
// 重构
function arrayReverse(array) {
if (!array || array.constructor !== Array) throw new TypeError(array + "not is Array!");
for (var i = 0; i < ~~(array.length / 2); i++) {
var temp = array[i];
array[i] = array[array.length - i - 1]
array[array.length - i - 1] = temp;
}
return array;
}
排序
Sort
- 减号表示从小到大,加号表示从大到小
var arr = [1531, 531, 35, 15, 13, 1, 354, 35, 4, 684, 6, 988, 34, 87, 46, 4, 1, 3]
console.log(arr.sort((a, b) => a - b));
//[1, 1, 3, 4, 4, 6, 13, 15, 34, 35, 35, 46, 87, 354, 531, 684, 988, 1531]
// 重构
function arraySort(array, callback) {
if (!array || array.constructor !== Array) throw new TypeError(array + "not is Array!");
if (typeof callback !== "function") throw new TypeError(callback + "is not Function!");
var temp;
for (var i = 0; i < array.length - 1; i++) {
for (var j = 0; j < array.length - i - 1; j++) {
if (callback(array[j], array[j + 1]) > 0) {
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
return array;
}
// 将价格从小到大排列
var arr = [
{ id: 1001, price: 3000, num: 2 },
{ id: 1002, price: 2000, num: 1 },
{ id: 1003, price: 1000, num: 2 },
{ id: 1004, price: 5000, num: 4 },
{ id: 1005, price: 4000, num: 2 },
{ id: 1006, price: 2000, num: 5 },
{ id: 1007, price: 1600, num: 1 },
]
arr.sort(function (a, b) {
return a.price - b.price
})
console.log(arr);
// 概率问题,0.5表示中间值,0.1表示概率在最前面
var arr = Array(100).fill(1).map(function (item, index) {
return index + 1
})
arr.sort(function () {
return Math.random() - 0.5
})
console.log(arr);
冒泡
- 修改原数组
// 排序
function bubbleSort(arr) {
var temp;
for (var i = 0; i < arr.length - 1; i++) {
for (var j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
选择
function selectSort(arr) {
for (let i = 0; i < arr.length - 1; i++) {
let min = i;
for (let j = min + 1; j < arr.length; j++) {
if (arr[min] > arr[j]) {
min = j;
}
}
let tmp = arr[min];
arr[min] = arr[i];
arr[i] = tmp;
}
return arr;
}
快排
// 重构
function quickSort(arr) {
if (arr.length < 2) return arr;
var index = ~~(arr.length / 2);
var center = arr.splice(index, 1)[0]
var left = [];
var right = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] <= center) left.push(arr[i]);
else right.push(arr[i]);
}
return quickSort(left).concat(center, quickSort(right))
}
桶排
// 去重排序
function bucketSort(arr) {
var obj = {};
for (var i = 0; i < arr.length; i++) {
obj[arr[i]] = arr[i];
}
return Object.values(obj);
}
// 直接排序,不进行去重
function bucketSort(arr) {
var obj = {};
for (var i = 0; i < arr.length; i++) {
if (!obj[arr[i]]) obj[arr[i]] = 0;
obj[arr[i]]++;
}
return Object.keys(obj).reduce(function (value, item) {
return value.concat(Array(obj[item]).fill(Number(item)));
}, [])
}
希尔
复杂度 空间复杂度 时间复杂度
二维数组和对象数组
- 创建二维数组
var arr = []
for (var i = 0; i < 10; i++) {
arr[i] = []
for (var j = 0; j < 10; j++) {
arr[i][j] = (i * 10) + j
}
}
console.log(arr);
- 查找数组中对象为22
var arr = [
{ a: 1, b: 2 },
{ a: 2, b: 12 },
{ a: 3, b: 32 },
{ a: 4, b: 22 },
{ a: 5, b: 72 },
]
var obj = arr.reduce(function (item) {
return item.b = 22
})
console.log(obj);
数组去重
修改原数组
for (var i = 0; i < arr.length; i++) {
for (var j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j]) {
arr.splice(j, 1)
j--
}
}
}
for (var i = 0; i < arr.length; i++) {
var index = arr.indexOf(arr[i], i + 1)
if (index > -1) {
arr.splice(index, 1)
i--
}
}
不修改原数组
var arr1 = arr.reduce(function (value, item) {
if (value.includes(item)) return value
value.push(item)
return value
}, [])
var arr1 = [];
abc: for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < arr1.length; j++) {
if (arr[i] === arr1[j]) continue abc;
}
arr1.push(arr[i]);
}
var arr1 = [];
for (var i = 0; i < arr.length; i++) {
if (arr1.includes(arr[i])) continue;
arr1.push(arr[i]);
}
数组合并
var arr = [1, 2, 4, 2, 3, 5, 1, 4];
var arr1 = [4, 6, 2, 4, 2, 8, 9];
// 方法一
var arr2 = arr.concat(arr1).reduce(function (value, item) {
if (value.includes(item)) return value
value.push(item)
return value
}, [])
// 方法二
var arr2 = arr1.reduce(deRepeat, arr.reduce(deRepeat, []));
function deRepeat(value, item) {
if (value.includes(item)) return value;
value.push(item);
return value;
}
字符类型方法
字符串的认识
- 获取字符串第几个字符,但是只读不可写
var str1 = "abcdef";
console.log(str1[0]); // a
- 获取字符串字符个数,只读不可修改
var str1 = "abcdef";
console.log(str1.length) // 6
- 通过指定的下标,查找所对应的字符串
var str1 = "abcdef";
console.log(str1.charAt(1)); // b
console.log(str1.charAt(5)); // f
charCodeAt
- 通过下标查找所对应字母的ASCII码值
var str1 = "abcdef";
console.log(str1.charCodeAt(0)) // 97
console.log(str1.charCodeAt(4)) // 101
fromCharCode()
- 将Unicode编码转换为字符
console.log(String.fromCharCode(97)) // a
// 创建中文字库对象
var obj = Array(0x9fd5 - 0x4e00).fill(1).reduce(function (value, item, i) {
value[i + 0x4e00] = String.fromCharCode(0x4e00 + i);
return value;
}, {});
console.log(obj)
fromCodePoint
- 返回使用指定的代码点序列创建的字符串。
// 获取26个英文字母
console.log(String.fromCodePoint(...Array(26).fill(1).map(function (item, index) {
return index + 97
})))
concat
var str1 = "abcdef";
var str2 = '123123是大股东 '
var str3 = str2.concat(str1)
console.log(str3); // 123123是大股东 abcdef
endsWith
// 是不是以a字符结束
console.log(str1.endsWith("a"))
// 第一项开始是不是以b字符结束
console.log(str1.endsWith("b",1))
console.log(str1.endsWith("c",2))
startsWith
// 是不是以a字符开始
console.log(str1.startsWith("a"))
// 第一项开始是不是以b字符开始
console.log(str1.startsWith("b",1))
console.log(str1.startsWith("c",2))
includes
- 判断字符串是否包含这个字符 返回true/false
// 查找对应字符下标,没有查找到返回-1
console.log(str1.indexOf("b"))
console.log(str1.indexOf("b",1))
console.log(str1.lastIndexOf("b"))
// 模糊查询
<input type="text" id="inputs">
<ul id="ul"></ul>
var arr = [
{ id: 1001, name: "计算器", price: 100 },
{ id: 1002, name: "计算机", price: 200 },
{ id: 1003, name: "手机", price: 300 },
{ id: 1004, name: "手办", price: 400 },
{ id: 1005, name: "办公室", price: 500 },
{ id: 1006, name: "公司", price: 600 },
{ id: 1007, name: "算术题", price: 700 },
]
var inputs, ul;
init();
function init() {
inputs = document.getElementById("inputs");
ul = document.getElementById("ul");
inputs.oninput = inputHandler;
}
// 模糊搜索
function inputHandler() {
// console.log(inputs.value)
ul.innerHTML = arr.reduce(function (value, item) {
if (item.name.indexOf(inputs.value) > -1) {
value += "<li>" + item.name + "-" + item.price + "</li>"
}
return value;
}, "")
}
replace
- 返回一个由替换值(
replacement)替换部分或所有的模式(pattern)匹配项后的新字符串 - replace替换的是第一个满足条件的元素
- replaceAll替换的是所有满足条件的元素
var str = "abcdecf";
console.log(str); // abcdecf
console.log(str.replace("c", "z")) // abzdecf
console.log(str.replaceAll("c", "z")) // abzdezf
padStart/padEnd
- 判断长度,并且在不满足长度的情况下在前面补字符或者后者补字符
padStart()方法用另一个字符串填充当前字符串(如果需要的话,会重复多次),以便产生的字符串达到给定的长度。从当前字符串的左侧开始填充。padEnd()方法会用一个字符串填充当前字符串(如果需要的话则重复填充),返回填充后达到指定长度的字符串。从当前字符串的末尾(右侧)开始填充。
console.log("a".padStart(2,"0")) // 不足前面补0 0a
console.log(String(~~(Math.random() * 50)).padStart(2, "0")) // 18
console.log(String(~~(Math.random() * 50)).padEnd(2, "0")) // 32
对象转字符串
var obj = {
a: 4,
b: 3,
d: 2,
e: 5
}
var str = Object.keys(obj).reduce(function (value, key) {
return value + (key).repeat(obj[key])
}, "");
console.log(str) // aaaabbbddeeeee
var obj = {
name: "zhangsan",
age: 30
}
var str = Object.keys(obj).reduce(function (value, key) {
return value + key + "=" + obj[key] + "&"
}, "").slice(0, -1)
console.log(str) // name=zhangsan&age=30
字符串转对象
var str = "http://www.163.com/index.html?name=zhangsan&age=30";
var obj = str.split("?")[1].split("&").reduce(function (value, item) {
var arr = item.split("=");
value[arr[0]] = isNaN(arr[1]) ? arr[1] : Number(arr[1]);
return value;
}, {})
console.log(obj) // {name: 'zhangsan', age: 30}
slice
slice()方法提取某个字符串的一部分,并返回一个新的字符串,且不会改动原字符串。
console.log("fghjk".slice(0, 3)) // fgh
console.log("fghjk".slice(2, 5)) // hjk
substr
- str,substr(从什么位置开始,截取的字符串长度是多少)
- 开始位置可以是负数
console.log("fghjklasdas".substr(-5, 3)) // asd
console.log("asdhjgaksjdha".substring(2, 5)) // dhj
console.log("fghjklasdasd".substring(5, 2)) // hjk
substring
- str.substring(开始位置,结束位置) 但是不允许有负数,但是这里可以反着截取,从后向前
split
- 切割
- 和join对应逆向方法
var str='abcd'
console.log(str.split('')) // ['a','b','c','d']
toUpperCase
- 转大写
console.log("asdasd".toUpperCase()); // ASDASD
// 首字母转换大写
var str = "i love javascript"
var str1 = str.split(" ").reduce(function (value, item) {
return value + item[0].toUpperCase() + item.slice(1) + " ";
}, "").slice(0, -1);
// var str1 = str.split(" ").map(function (item) {
// return item[0].toUpperCase() + item.slice(1);
// }).join(" ");
console.log(str1)
toLowerCase
- 转小写
console.log("ASDASD".toLowerCase()); // asdasd
trim
- 去除前后空格
var str = " a sa da sda sd ";
// 去掉前后空格
console.log(str.trim()); // a sa da sda sd
trimStart
- 去除前面空格
console.log(str.trimStart()); // a sa da sda sd
trimLeft
- 去除前面空格
console.log(str.trimLeft()); // a sa da sda sd
####trimEnd
- 去除后面空格
console.log(str.trimEnd()); // a sa da sda sd
trimRight
- 去除后面空格
console.log(str.trimRight()); // a sa da sda sd
数学方法
Pi
- 弧度和角度转换
// Math.PI/180 * 角度 = 弧度
var angle = Math.PI/180*60
- 所有三角函数中,方法中必须使用弧度,所以必须将角度转换为弧度
console.log(Math.PI/180*90)
绝对值abs
console.log(Math.abs(-5)); // 5
数值取整
- 向下取整
console.log(Math.flor(3.5))
- 向上取整
console.log(Math.ceil(3.5))
- 四舍五入
console.log(Math.round(3.5)) // 4 console.log(Math.round(-3.4)); // -3 console.log(Math.round(-3.5)); // -3 console.log(Math.round(-3.6)); // -4
- 四舍五入技巧: 拆分法 ==> 例如: 3.5 = 3 + 0.5 -3.4 = -3 + 0.4 -3.6 = -3 + 0.6
求幂
console.log(Math.pow(3, 3)) // 27
求平方根
console.log(Math.sqrt(4)) // 2
console.log(Math.pow(9, 1 / 2)) // 3
console.log(Math.pow(27, 1 / 3)) // 3