原生js的数组常用方法

115 阅读5分钟

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