快收藏!這些JS數(shù)組小技巧
點擊上方 程序員成長指北,關(guān)注公眾號
回復1,加入高級Node交流群
2021入秋的第一篇推文我想來聊聊JS處理數(shù)組有哪些小妙招值得我們關(guān)注?
數(shù)組置空
數(shù)組置空?這不是基操嗎?我直接甩一手代碼就問怕不怕
let arr = [1,2,3]
arr = []
其實啊arr=[]是將arr數(shù)據(jù)引用到空數(shù)組[]中,其他引用arr數(shù)據(jù)的變量是不受影響的。這就意味著,數(shù)組先前的內(nèi)容依舊保存在內(nèi)存中,當數(shù)據(jù)量比較大時,可以會造成內(nèi)存泄漏
。那么如何避免類似的隱患?
let arr = [1,2,3]
arr.length = 0
這樣就可以徹底清空arr數(shù)據(jù)的內(nèi)容,先前引用arr數(shù)據(jù)的內(nèi)容也會一并消失。
數(shù)組頭部插入數(shù)據(jù)
數(shù)據(jù)頭部插入數(shù)據(jù),你是否還在用JS提供的unshift()方法
let arr = [1,2,3]
arr.unshift('我是頭部插入的數(shù)據(jù)')
console.log(arr) // => ['我是頭部插入的數(shù)據(jù)', 1, 2, 3]
現(xiàn)在21世紀了,得用新的思路去解決問題,考慮到性能的問題,現(xiàn)在我們可以采用以下的辦法實現(xiàn)數(shù)組插入數(shù)據(jù)
let arr = [1,2,3]
let newArr = ['haha'].concat(arr)
console.log(newArr) // => ['haha',1, 2, 3]
這樣性能就能比較好?我們口說無憑,直接測試一下:
let arr = []
console.time('開始測試 100次 數(shù)據(jù)操作時 concat 的性能')
for (let i = 0; i < 100; i++) {
arr.concat(['concat在測試'])
}
console.timeEnd('開始測試 100次 數(shù)據(jù)操作時 concat 的性能')
console.time('開始測試 100次 數(shù)據(jù)操作時 unshift 的性能')
for (let i = 0; i < 100; i++) {
arr.unshift(['unshift在測試'])
}
console.timeEnd('開始測試 100次 數(shù)據(jù)操作時 unshift 的性能')
100次數(shù)據(jù)量的耗時結(jié)果:
10000次數(shù)據(jù)量的耗時結(jié)果:
100000次數(shù)據(jù)量的耗時結(jié)果:
這簡直就是碾壓了 unshift 的速度了。所以我們在操作數(shù)組頭部插入數(shù)據(jù)的時候可以選用 let newArr = ['haha'].concat(arr) 這種方式
數(shù)組尾部插入數(shù)據(jù)
同樣的,在數(shù)組尾部插入數(shù)據(jù)你是否還在用這樣的方法?
let arr = [1,2,3]
arr.push(4)
console.log(arr) // => [1,2,3,4]
其實,我們都忽略了數(shù)組本身就很方便的數(shù)據(jù)插入邏輯
let arr = [1,2,3]
arr[arr.length] = 4
console.log(arr) // => [1,2,3,4]
直接上測試用例
let arr = []
console.time('開始測試 100次 數(shù)據(jù)操作時 push 的性能')
for (let i = 0; i < 100; i++) {
arr.push('push在測試')
}
console.timeEnd('開始測試 100次 數(shù)據(jù)操作時 push 的性能')
console.time('開始測試 100次 數(shù)據(jù)操作時 length 的性能')
for (let i = 0; i < 100; i++) {
arr[arr.length] = 'length在測試'
}
console.timeEnd('開始測試 100次 數(shù)據(jù)操作時 length 的性能')
100次數(shù)據(jù)量的耗時結(jié)果:
10000次數(shù)據(jù)量的耗時結(jié)果:
100000次數(shù)據(jù)量的耗時結(jié)果:
可以看到是略勝一點,有時又稍微慢點,總體上來說 arr[arr.length] = 'length在測試'會稍微快點點。
數(shù)組去重
數(shù)組去重這個方法大家就用得比較多了
let arr = ['9', '1', '2', '3', '4', '5', '1', '3', '2', '6', '2']
console.log(Arry.from(new Set(arr))) // =>['9', '1', '2', '3', '4', '5', '6']
//倘若不用Arry.from()呢?
console.log(new Set(arr)) // => {'9', '1', '2', '3', '4','5','6'}
復制數(shù)組
利用 擴展運算法 實現(xiàn)數(shù)組的復制。值得注意的是,擴展運算符 的使用是深拷貝還是淺拷貝得看數(shù)據(jù)源的數(shù)據(jù)類型。如果只是一層數(shù)組或是對象,其元素只是簡單類型的元素,那么屬于深拷貝。
let arr = ['張三', '李四', '王五', '找六', '張三']
let test = [...arr] // => 深拷貝
console.log(test) // => ['張三', '李四', '王五', '找六', '張三']
let obj = {
age: 18,
name: '小明',
address: {
city: '東莞'
}
}
let newObj = {...obj}
console.log(newObj.address.city) // => 東莞
由上可見,擴展運算符 還可以將數(shù)組轉(zhuǎn)為對象
let arr = ['張三', '李四', '王五', '找六', '張三']
let obj = { ...arr }
console.log(obj) // => {0: '張三', 1: '李四', 2: '王五', 3: '找六', 4: '張三'}
合并數(shù)據(jù)
常用的合并數(shù)據(jù) concat 這里就不提了,這里我們使用 擴展運算符 來合并數(shù)據(jù)
let arr2 = ['張三', '李四', '王五', '找六', '張三']
let arr3 = ['小明', '小紅', '王五', '張三']
console.log([...arr2, ...arr3]) // => ['張三', '李四', '王五', '找六', '張三', '小明', '小紅', '王五', '張三']
//很明顯這樣的合并不是我們想要的效果,我們需要對數(shù)組去重
console.log(Array.from(new Set([...arr2, ...arr3])))
// => ['張三', '李四', '王五', '找六', '小明', '小紅']
數(shù)組交集
講到合并必然會想到交集?;叵胍幌?,之前我們?nèi)蓚€數(shù)組的交集是不是直接遍歷兩個數(shù)組,然后比較值來完成的?今天,我們利用 filter 跟ES7的 includes 方法來完成
let arr2 = ['張三', '李四', '王五', '找六', '張三']
let arr3 = ['小明', '小紅', '王五', '張三']
let jiaoji = [...new Set(arr2)].filter(item => arr3.includes(item)) // => ['張三', '王五']
獲取數(shù)組的隨機值
使用Math.floor()和Math.random()方法獲得一個隨機值
let arr2 = ['張三', '李四', '王五', '找六', '張三']
console.log(arr2[Math.floor(Math.random() * (arr2.length))]) // => 張三
獲取最后出現(xiàn)的下標
lastIndexOf 可以幫助我們獲取數(shù)組最后出現(xiàn)字符的下標
let arr2 = ['張三', '李四', '王五', '找六', '張三']
console.log(arr2.lastIndexOf('張三')) // => 4
數(shù)組倒序
let arr2 = ['張三', '李四', '王五', '找六']
console.log(arr2.reverse()) // => ['找六', '王五', '李四', '張三']
說到 reverse 這里插一句,實現(xiàn)字符串倒敘可以怎么完成?我們還是利用數(shù)組的 reverse 方法。首先將字符串切割為數(shù)組,然后反轉(zhuǎn)數(shù)組,最后拼接數(shù)組為字符串
let str = 'abcdef'
console.log(atr.split('').reverse().join('')) // => fedcba
替換任意位置的值
splice() 方法從數(shù)組中添加/刪除項目,然后返回被刪除的數(shù)據(jù)。該方法會改變原始數(shù)組。注意插入值的位置!
let arr2 = ['張三', '李四', '王五', '找六', '張三']
arr2.splice(1, 3, '替換值1', '替換值2', '替換值3')
console.log(arr2) // => ['張三', '替換值1', '替換值2', '替換值3', '張三']
arr2.splice(0, 1) // => 不傳入3+n值的時候代表刪除數(shù)據(jù)
console.log(arr2) // => ['張三', '替換值1', '替換值2', '替換值3', '張三'] // => ['李四', '王五', '找六', '張三']
遍歷數(shù)組
平時我們使用最多的就是數(shù)組的 .map 方法,其實還有一個方法也能達到一樣的目的,那就是Array.from
let list = [
{ name: '小明', age: 11 },
{ name: '小紅', age: 13 },
{ name: '校長', age: 15 }
]
Array.from(list, (item) => item.str = `名字:${item.name},年齡:${item.age}`)
console.log(list)
結(jié)果就是可以直接改變list的數(shù)據(jù):
去掉數(shù)據(jù)中的虛假值
JS中虛假值有:false、0、''、null、NaN、undefined、-0
let arr4 = ['小明', '小藍', '', false, ' ', undefined, null, 0, NaN, true]
console.log(arr4.filter(Boolean)) // => ['小明', '小藍', ' ', true]
值得注意的是' ' 并不是虛假值
數(shù)組求和
通常想到的就是直接遍歷數(shù)組,然后累加,其實 reduce 有很多的妙用
let arr2 = ['張三', '李四', '王五', '找六', '張三']
console.log(arr2.reduce((a, b) => a + b)) // => 張三李四王五找六張三
let arr5 = [1, 2, 3, 4]
console.log(arr5.reduce((a, b) => a + b)) // => 10
當數(shù)組中純數(shù)字類型的話得到的值是數(shù)字,簡單類型的字符串的話是字符串
最后溫馨?:入秋了,記得穿件外套,我就不了,廣東不配
我組建了一個氛圍特別好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你對Node.js學習感興趣的話(后續(xù)有計劃也可以),我們可以一起進行Node.js相關(guān)的交流、學習、共建。下方加 考拉 好友回復「Node」即可。

“分享、點贊、在看” 支持一波 
