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