摘要:數(shù)組索引只是具有整數(shù)名稱的枚舉屬性,并且與通用對象屬性相同。利用的解構(gòu)賦值解構(gòu)賦值尾遞歸優(yōu)化遞歸非常耗內(nèi)存,因為需要同時保存成千上百個調(diào)用幀,很容易發(fā)生棧溢出。而尾遞歸的實現(xiàn),往往需要改寫遞歸函數(shù),確保最后一步只調(diào)用自身。
一.前言
因為在工作當(dāng)中,經(jīng)常使用到j(luò)s的數(shù)組,而其中對數(shù)組方法的使用也是很頻繁的,所以總是會有弄混或者概念不夠清晰的狀況,所以,寫下這篇文章整理一番,本文有對幾乎所有數(shù)組的方法的介紹,此外還有非常實用的一些數(shù)組操作比如亂序去重和斐波那契數(shù)列求值等等,總之干貨滿滿~~
二.JS中的Array方法 1.檢測數(shù)組//instanceof 測試某個對象是否由某個指定的構(gòu)造器創(chuàng)建 [1,2,3] instanceof Array //true "1" instanceof Array // false //比instanceof更可靠 Array.isArray Array.isArray([1,2,3]); //true //Object對象的toString()方法,可以返回所創(chuàng)建對象的內(nèi)部類名 Object.prototype.toString.call([1,2,3]); //"[object Array]" Object.prototype.toString.call("a"); //"[object String]"2.轉(zhuǎn)換方法
const test = [1,2,3]; test.toString(); //"1,2,3" test.valueOf(); //[1,2,3] //toLocaleString大部分為返回與toString相同的結(jié)果,區(qū)別之處在于會調(diào)用每一項的toLocaleString()方法 test.toLocaleString([1,2,3]); //[1,2,3]; const testStr = test.join("|"); //"1|2|3" testStr.split("|"); // [1,2,3];3.棧方法(push和pop 尾部操作)
const test = new Array(); const count= test.push("a","b"); //count為操作完后的數(shù)組長度 console.log(count); //2 const count1 = test.push("c"); console.log(count1); //3 const item = test.pop(); console.log(item); //"c"4.隊列方法(shift和unshift 頭部操作)
const test = [1,2,3]; const item = test.shift(); console.log(item); //1 console.log(test); //[2,3];5.重排序方法
const test = [1,2,3]; const test1 = test.reverse(); // [3,2,1] test1.sort(); //[1,2,3]6.操作方法
//concat會創(chuàng)建當(dāng)前數(shù)組的一個副本再進(jìn)行操作,不影響原數(shù)組 const test = [1,2,3]; const test1 = [1,2,3].concat([4,5]); console.log(test); //[1,2,3] console.log(test1); //[1,2,3,4,5] //slice接受一個或兩個參數(shù),返回起始和結(jié)束位置之間的項(但不包括最后位置的項),不影響原數(shù)組 const test = [1,2,3,4]; const test1 = test.slice(0); //[1,2,3,4] const test2 = test.slice(1,3); //[2,3] console.log(test); //[1,2,3,4] 原數(shù)組未改變 //splice 可用作刪除、插入和替換,改變原數(shù)組 const test = [1,2,3,4,5]; test.splice(1,2); //test為[1,4,5] test.splice(1,0,"a","b"); //test為[1,"a","b",2,3,,4,5] test.splice(2,1,"c"); //test為[1,2,"c",4,5]7.位置方法
const test = [1,2,3,4,5,4,3,2]; test.indexOf(4); //3 test.lastIndexOf(4); //5 test.indexOf("4"); //-1 必須全相等(===)8.循環(huán)方法
1.filter() 對數(shù)組的每一項允許給定函數(shù),返回該函數(shù)會返回true的項組成數(shù)組,不會改變原數(shù)組
const test = [1,2,3,4,5]; const test1 = test.filter((item) => item > 3); console.log(test); //[1,2,3,4,5]; console.log(test1); //[4,5];
2.map() 對數(shù)組的每一項執(zhí)行給定函數(shù),返回每次函數(shù)調(diào)用的結(jié)果組成的數(shù)組,不會改變原數(shù)組
const test = [{a:1,b:2},{a:3,b:4},{a:5,b:6}]; const test1 = test.map((item) => item["a"]); console.log(test); //[{a:1,b:2},{a:3,b:4},{a:5,b:6}] console.log(test1); //[1,3,5]
3.forEach 對數(shù)組的每一項運行給定函數(shù),沒有返回新數(shù)組,沒有返回值
const test = [[1],[2]]; test.forEach((item) => item.push(1)); console.log(test); //[[1,1], [2,1]]9.其他的循環(huán)方法
1) 普通for循環(huán)(性能較好)
const test = [1,2,3,4]; for(let i=0,len=test.length;i 2) for in 以【任意】順序遍歷一個對象的可枚舉屬性,所以不太建議用來遍歷一個數(shù)組,原因如下。for...in不應(yīng)該用于迭代一個 Array,其中索引順序很重要。數(shù)組索引只是具有整數(shù)名稱的枚舉屬性,并且與通用對象屬性相同。不能保證for ... in將以任何特定的順序返回索引。for ... in循環(huán)語句將返回所有可枚舉屬性,包括非整數(shù)類型的名稱和繼承的那些,即它返回的除了數(shù)字索引外還有可能是你自定義的屬性名字。const person = {work:"coder",age:"24",sex: "female"}; for(prop in person) { console.log(`Jchermy[${prop}]=${person[prop]}`); } //Jchermy[work]=coder //Jchermy[age]=24 //Jchermy[sex]=female3)for..of語句在可迭代的對象上創(chuàng)建了一個循環(huán)(包括Array, Map, Set, 參數(shù)對象( arguments) 等等),
對值的每一個獨特的屬性調(diào)用一個將被執(zhí)行的自定義的和語句掛鉤的迭代。for..of 作為es6中引進(jìn)的循環(huán),主要是為了補全之前for循環(huán)中的以下不足 :forEach 不能 break 和 return;
for-in 它不僅遍歷數(shù)組中的元素,還會遍歷自定義的屬性,甚至原型鏈上的屬性都被訪問到。而且,遍歷數(shù)組元素的順序可能是隨機的。
而相比之下for...of可以做到:與forEach 相比,可以正確響應(yīng) break, continue, return。
for-of 循環(huán)不僅支持?jǐn)?shù)組,還支持大多數(shù)類數(shù)組對象,例如 DOM nodelist 對象。
for-of 循環(huán)也支持字符串遍歷,它將字符串視為一系列 Unicode 字符來進(jìn)行遍歷。
for-of 也支持 Map 和 Set (兩者均為 ES6 中新增的類型)對象遍歷。
let test = [3, 5, 7]; test.foo = "hello"; for (let i in test) { console.log(i); // "0", "1", "2", "foo" } for (let i of test) { console.log(i); // "3", "5", "7" // 注意這里沒有 hello }從以上我們可以看出for..of和for...in的區(qū)別 1. for...in循環(huán)出的是key,for...of循環(huán)出的是value 2. 作用于數(shù)組的for-in循環(huán)除了遍歷數(shù)組元素以外,還會遍歷自定義屬性,比如例子中的foo屬性。for...of循環(huán)不會循環(huán)對象的key,只會循環(huán)出數(shù)組的value。4)do...while 語句一直重復(fù)直到指定的條件求值得到假(false)
let i = 0; do { i += 1; console.log(i); } while (i < 5); //1 //2 //3 //4 //55) while只要指定的條件為真就會一直執(zhí)行它的語句塊
let n = 0; let x = 0; while(n<3) { n++; x +=n; console.log(n,xhdf); } // 1 1 // 2 3 // 3 6三、常用數(shù)組操作 1.數(shù)組亂序將一個數(shù)組完全打亂,然后返回打亂后的數(shù)組。也稱為洗牌算法。
1) 利用Math.random()和sort()結(jié)合
const test = [1,2,3,4]; test.concat().sort(()=> Math.random() - 0.5); // [2, 4, 1, 3]這個方法貌似可以實現(xiàn)我們要的結(jié)果,但是實際上它并不完全是隨機的,而是越大的數(shù)字出現(xiàn)在越后面的概率越大。具體原因可以看這篇文章數(shù)組的完全隨機排列
2) 遍歷原數(shù)組,然后隨機產(chǎn)生下標(biāo),將這個下標(biāo)的值push到新的數(shù)組中,并隨即刪除這值,注意不是用delete,那樣并不會改變數(shù)組的長度,效率不高,使用splice較好.
function shuffle(array) { let i,n=array.length,copy=[]; while(n) { i = Math.floor(Math.random()*n--);//n--是先與Math.random相乘再減一 copy.push(array.splice(i, 1)[0]); } return copy; } const test = [1,2,3,4,5]; console.log(shuffle(test)); //[2, 5, 4, 3, 1]3)Fisher–Yates shuffle 算法 隨機從數(shù)組中抽出一個元素,然后與最后個元素交換,相當(dāng)于把這個隨機抽取的元素放到了數(shù)組最后面去,表示它已經(jīng)是被隨機過了,同時被換走的那個元素跑到前面去了,會在后續(xù)的重復(fù)操作中被隨機掉。一輪操作過后,下一輪我們只在剩下的n-1個元素也就是數(shù)組的前n-1個元素中進(jìn)行相同的操作,直到進(jìn)行到第一個。
function shuffle(array) { let i, n=array.length; while(n) { i = Math.floor(Math.random()*(n--)); t = array[i] array[i] = array[n]; array[n] = t; n--; } return array; } var test = [1,2,3,4]; console.log(shuffle(test.concat()));//傳入數(shù)組的副本2. 求斐波那契序列的某一項的值ps:這一題的解法有很多種,以下僅列出幾種
1) 首先祭出最經(jīng)典的解法,利用遞歸求值。
function fibonacci(n) { if(n==0 || n==1 ) { return n; } return fibonacci(n-1)+fibonacci(n-2); } const test = fibonacci(4); //3這種方法的問題是很多值會重新求值,效率很低,因此并不推薦。
2)利用ES6的解構(gòu)賦值const fibonacci =(n)=>{ let a = 0; let b= 1; let i = 2; while(i++ <= n){ [a, b] = [b, a+b]; //解構(gòu)賦值 } return b; } fibonacci(4); //33) 尾遞歸優(yōu)化
遞歸非常耗內(nèi)存,因為需要同時保存成千上百個調(diào)用幀,很容易發(fā)生‘棧溢出’。但對于尾遞歸優(yōu)化來說,由于只存在一個調(diào)用幀,所以永遠(yuǎn)不會發(fā)生棧溢出。而尾遞歸的實現(xiàn),往往需要改寫遞歸函數(shù),確保最后一步只調(diào)用自身。做到這一點的方法,就是把所有用到的內(nèi)部變量改寫成函數(shù)的參數(shù).function fibonacci(n, n1=0, n2=1){ if(n <=1) { return n2; } return fibonacci(n-1, n2, n1 + n2); } fibonacci(6); //84)利用緩存值減少重復(fù)求值
function fibonacci(){ var cache = { 0:0, 1:1 } return function _fibonacci(n) { return typeof cache[n] === "number" ? cache[n]: cache[n] = _fibonacci(n-1) + _fibonacci(n-2); } } const f = fibonacci(); f(9); //343.數(shù)組排序1)最常用的利用sort()排序,僅適用于純數(shù)字?jǐn)?shù)組
//升序 function asc(arr){ return arr.sort((a,b)=> {return a-b;}) } asc([6,3,4,2]);//[2,3,4,6] //降序 function desc(arr){ return arr.sort((a,b)=> {return b-a;}) } desc([4,3,2,5]); //[5, 4, 3, 2]2)由對象組成的數(shù)組,支持根據(jù)對象的某個屬性排序
const sortByProp = (name)=>{ return (f, s) => { var a, b; if (typeof f === "object" && typeof s === "object" && f && s) { a = f[name]; b = s[name]; if(a === b) { return 0; } else { return a < b ? -1 :1; } } else { throw new TypeError("數(shù)組必須由對象組成"); } }; }; const test = [{age:27, name:"xiaomi"},{age:17, name:"amy"},{age: 24, name: "Jchermy"}]; test.sort(sortByProp("age")); //[{age:17, name:"amy"},{age: 24, name: "Jchermy"}, {age:27, name:"xiaomi"}];4.數(shù)組去重1)利用array_filter()
function unique(arr){ let uniqueArr = []; uniqueArr = arr.filter((item) =>{ return uniqueArr.includes(item) ? "" : uniqueArr.push(item); }) return uniqueArr; }; unique([1,2,3,1,6,3,2,7]); //[1,2,3,6,7];2)利用es6中的Map()
function unique(arr) { const seen = new Map(); return arr.filter((item) => !seen.has(item) && seen.set(item, 1)); } unique([11,2,3,4,4,2,5]); //[11, 2, 3, 4, 5]3)利用es6中的Set()
function unique(arr){ return [...new Set(arr)]; //將set結(jié)構(gòu)轉(zhuǎn)為數(shù)組 } unique([1,2,2,3,7,3,8,5]); //[1, 2, 3, 7, 8, 5]5.數(shù)組去除空值function filter_array(array) { return array.filter(item=>item); } const test = [undefined,undefined,1,"","false",false,true,null,"null"]; filter_array(test); //[1, "false", true, "null"]四.結(jié)語呼,寫了好幾天的文章終于寫完啦,撒花~~
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/95116.html
摘要:本文對一些排序算法進(jìn)行了簡單分析,并給出了的代碼實現(xiàn)。平均時間復(fù)雜度不好分析,它是冒泡排序是穩(wěn)定的排序算法。冒泡排序是原地排序算法原地排序指的是空間復(fù)雜度是的排序算法。歸并排序,會將數(shù)組從中間分成左右兩部分。 本文對一些排序算法進(jìn)行了簡單分析,并給出了 javascript 的代碼實現(xiàn)。因為本文包含了大量的排序算法,所以分析不會非常詳細(xì),適合有對排序算法有一定了解的同學(xué)。本文內(nèi)容其實不...
摘要:哪吒社區(qū)技能樹打卡打卡貼函數(shù)式接口簡介領(lǐng)域優(yōu)質(zhì)創(chuàng)作者哪吒公眾號作者架構(gòu)師奮斗者掃描主頁左側(cè)二維碼,加入群聊,一起學(xué)習(xí)一起進(jìn)步歡迎點贊收藏留言前情提要無意間聽到領(lǐng)導(dǎo)們的談話,現(xiàn)在公司的現(xiàn)狀是碼農(nóng)太多,但能獨立帶隊的人太少,簡而言之,不缺干 ? 哪吒社區(qū)Java技能樹打卡?【打卡貼 day2...
摘要:被調(diào)用時,等參數(shù)將置于實參之前傳遞給被綁定的方法。它返回由指定的值和初始化參數(shù)改造的原函數(shù)拷貝。一個綁定函數(shù)也能使用操作符創(chuàng)建對象這種行為就像把原函數(shù)當(dāng)成構(gòu)造器。其實這個思路也是庫如何實現(xiàn)繼承的方法。他的函數(shù)如下最后一步是將的指回。 update: 2018-06-08 原文鏈接 為什么要自己去實現(xiàn)一個bind函數(shù)? bind()函數(shù)在 ECMA-262 第五版才被加入;它可能無法在所...
摘要:原文地址不管是在面試中還是在筆試中,我們都會被經(jīng)常問到關(guān)于數(shù)組的一些算法,比方說數(shù)組去重數(shù)組求交集數(shù)組擾亂等等。今天抽點時間把中的一些常用的數(shù)組算法做一下總結(jié),以方便大家面試筆試或者日常開發(fā)過程中用到。 原文地址:http://www.cnblogs.com/front-... 不管是在面試中還是在筆試中,我們都會被經(jīng)常問到關(guān)于javascript數(shù)組的一些算法,比方說數(shù)組去重、數(shù)組求...
摘要:不過讓流行起來的原因應(yīng)該是是目前所有主流瀏覽器上唯一支持的腳本語言。經(jīng)過測試,數(shù)字字符串布爾日期可以直接賦值,修改不會產(chǎn)生影響。再考慮對象類型為或者的情況。對于結(jié)果聲明其類型。判斷對象的類型是還是,結(jié)果類型更改。 轉(zhuǎn)載自我的個人博客 歡迎大家批評指正 1. 第一個頁面交互 這里最需要學(xué)習(xí)的老師的代碼中,每一部分功能都由函數(shù)控制,沒有創(chuàng)建一個全部變量。且最后有一個函數(shù)來控制執(zhí)行代碼...
閱讀 3218·2023-04-26 02:27
閱讀 2143·2021-11-22 14:44
閱讀 4092·2021-10-22 09:54
閱讀 3199·2021-10-14 09:43
閱讀 752·2021-09-23 11:53
閱讀 12715·2021-09-22 15:33
閱讀 2711·2019-08-30 15:54
閱讀 2685·2019-08-30 14:04