下面是我對 ES3/ES5/ES6 一些數組操做的總結,附帶了一些我曾經遇到和用上的一些實際需求。html
map處有待更內容。前端
好像沒有什麼可說的?react
var a = [1]; a.push(2); console.log(a); // [1,2] console.log(a.push(8)); //3
push 和 pop 組成了後進先出的棧數據結構。es6
var a = [1,2,3]; console.log(a.pop()); // 3 console.log(a); // [1,2]
經過這個函數,能夠幫咱們實現一道OJ題目,輸出文件的後綴名面試
const getExtName = (filename) => { let position = filename.indexOf('.'); if (position !== 0 && position !== -1) { filename = filename.split('.'); postfix = filename.pop(); return '.' + postfix } else { return '' } }; console.log(getExtName('xx.avi')); // .avi
它接受0參數或者1個參數,如果傳了多個參數只有第一個是有效的。redux
古代的前端代碼或者古代的博客每每能看到這樣的東西(哦,讓我想起來了 Ext 的 tpl,也就是 JSX 語法的前前前代思想吧)segmentfault
var array = ['1','2','3']; var html="<h1>"+array.join("</h1><h1>")+"</h1>";
上述能夠生成用array做爲數據的指定結構的html.
經過 join,咱們可以將[數組]變爲[字符串],而咱們若要倒着來,能夠用 split數組
'a,b,c'.split(','); // ["a", "b", "c"] 'a,b,c'.split(',').join(',') // 'a,b,c'
結束位置還能夠是負數( 實際計算爲:該負數 + 數組長度)數據結構
結束位置小於起始位置,返回 空數組 []dom
var a = [1, 2, 3]; console.log(a.slice(1)); // [2, 3] console.log(a.slice(1, 2)); // [2] console.log(a); // [1, 2, 3] - 原數組沒有被改變 console.log(a.slice(1, -1)); // (-1 + 3) = 2 => a.slice(1, 2) => [2] console.log(a.slice(1, -100)); // []
slice 有一個挺經典的的代碼: [rgb顏色值轉換爲十六進制]
rgb值 (0, 0, 0) ~ (255, 255, 255),十六進制 #000000 ~ #ffffff
const rgbToHex = (color) => { let rgb = color.split(','); // 將 rgb 字符串分解,例子:'rgb(1, 1, 1)',獲得 ['rgb(1', '1,', '1)'] let r = parseInt(rgb[0].split('(')[1]), // 去掉數組第一項的多餘的東西 g = parseInt(rgb[1]), // 第二項自己很乾淨 b = parseInt(rgb[2].split(')')[0]); // 同第一項註釋 return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); // 這裏採用了位移操做 256 * 256 * 256 => 2^8 * 2^8 * 2^8 // 這裏的 (1<<24) 是爲了防止咱們的最高位的 r 顏色數字小於 16 的狀況,出現了五位數的狀況,如 #10000,顏色值嘛,得是六位的 } let color = 'rgb(10,128,233)'; console.log(rgbToHex(color));
(1<<24)是爲了規避 rgb 最高的 r 轉化的數字 < 16 的狀況
經過slice(1),咱們很容易地把多加上的那位1給去掉啦~是否是很取巧,我反正感受這題、這需求挺經典的。
這裏鄭重地提一句,字符串不能借用splice,即便使用了Array.porotpye.splice.call,由於在規範中,字符串是不可變的,使用splice會改變原數組。因此slice能夠在字符串中用,而splice不能。因此,若是咱們要在字符串中使用,須要注意。a.轉換成數組 b.注意splice返回的是被替換的東西,而不是自己。
以上同理。pop、push、reverse等改變原數組的,在 string 上都不能經過 call 來借用哦。
參數有三:
1.[開始位置]: 當只有1個參數的時候:從數組的開始位置刪掉剩下的全部數據,返回刪掉的數據。
slice就像只是咱們想象中的裁剪,而splice則是現實中的,從splice中醒來,已經是物是人非。splice是直接對數組進行操做的。
var array = [15, 5, 10, 2, 0]; console.log(array.splice(1)); // [5, 10, 2, 0] console.log(array); // [15]
var array = [15, 5, 10, 2, 0]; array.splice(1, 2); console.log(array); // [15, 2, 0]
3.[開始位置,截斷個數,插入的數據]: (start, cutLen, data): 以 start 爲起點, cutLen 爲長度,刪掉 [start, start + cutLen] 的元素,並填充 data 到刪除的位置
var array = [15, 5, 10, 2, 0]; array.splice(2, 2, 8); console.log(array); // [15, 5, 8, 0]
和pop差很少
var a = [1,2,3]; console.log(a.shift()); // 1 console.log(a); // [2,3]
pop,unshift,shift,push 這幾個都是直接對原數組進行操做的。
unshift和shift組成的數據結構也是棧,只是棧頂和棧尾位置交換了罷了。
var a = [1,2,3]; console.log(a.unshift(4)); // 4 console.log(a); // [4,1,2,3]
concat是不會改變原來的數組的
var a = [1,4]; var b = [2,4]; var c = []; console.log(c.concat(a,b)); // [1,4,2,4] console.log(a,b); // [1,4] [2,4]
無參數,無視參數, !!!!!操做的是數組自己,會改變原數組
var a = [1,2,3,5]; console.log(a.reverse()); // [5,3,2,1]
參數:fn(a,b):比較函數,無參數的時候按照字母表 ASCII 升順排序
var a = [1, 2, 3, 5, 10, 25]; console.log(a.sort()); // [1, 10, 2, 25, 3, 5]
看,咱們發現了什麼?這個排序結果明顯不是咱們所想要的結果,對吧哈哈?是否是頗有趣!
這是由於
sort()
默認對每個 子項 調用轉型方法toString()
,以後才進行判斷。而這個時候實際上是根據 ASCII 碼的大小來判斷的。所以 "15" < "5"。先比較第一位,再比較第二位。
即便每一項都是 Number
,若是咱們不後期加工,sort()
比較的也是每一項轉化爲的String
的大小。
那麼就讓咱們來實現一下其內部的方法使得 sort 可以按照咱們的預期工做吧!
var a = [1, 2, 3, 5, 10, 25]; a.sort((a, b) => a - b); console.log(a); // [1, 2, 3, 5, 10, 25]
我已經總結出來了一個規律。正所謂後來居上
return a-b;
便是從小到大(a-b)排序(b是在後面的,所謂後來)return b-a;
便是從大到小(b-a)排序let obj_list = [{ name: 'li', value: 99 }, { name: 'chen', value: 100 }, { name: 'huang', value: 1 }] console.log(obj_list.sort((a, b) => { return a.value - b.value })) // 排序結果:'huang','li','chen'
3.當compare函數返回任何小於0的值時,它將使第2個參數的索引值小於第1個參數的索引值
因此!!!若是咱們要亂序,咱們只要讓返回的隨機數 大於0和小於0 的機率同樣便可!上代碼:
var a = [1, 2, 3, 5, 10, 25]; a.sort((a, b) => 0.5 - Math.random()); console.log(a);
咱們曾經全部的複雜的,麻煩的操做,在新技術中,都被簡化,就像拖把和拖把同樣,這就是進步,擁有進步能力的語言每每不容易被這個時代所淘汰。
咱們能夠首先來用ES3來模擬一下先,有助於咱們理解。
Array.prototype.indexOf = function (index) { var res = -1, now = null, len = this.length; if (len == 0) return res; for (var i = 0; i < len; i++) { now = this[i]; if (index == now) { res = i; break; } } return res; } var test = ['234', '23424', '30']; console.log(test.indexOf('30'));
參數爲function類型,默認有傳參(遍歷數組內容,對應數組索引,數組自己)
在這裏引用一個segmentfault的回答:https://segmentfault.com/q/1010000006127658?_ea=1022444,如下爲引用的內容
題目之添加一個 fullName
不用 forEach
var users = [ { lastName: 'Li', firstName: 'Lei' }, { lastName: 'Han', firstName: 'Meimei' } ]; // 在這裏,咱們用原始的語法處理 for (var i = 0; i < users.length; i++) { users[i].fullName = users[i].firstName + users[i].lastName; } console.log(users);
使用 forEach
users.forEach(function(user,index,arr){ user.fullName = user.firstName + user.lastName; }); console.log(users);
你可能認爲這裏的 forEach 其實改變了數組的值,其實否則。
只需知道,引用對象是不一樣的,他們指向的是一個內存位置,而非實際的對象。
var arr = [1, 2, 3]; arr.forEach(item => { item = 8; }); console.log(arr); // [1, 2, 3]
咱們可以在 Redux 中的 reducer 看到大量的 map 函數,由於 redux 追求這種函數式極簡的酷炫的風格;
Vue 中的 v-for 本質上就是 map 實現的;
map是指映射,和英文中的地圖不一樣。
var a = [1, 32, 442, 234]; b = a.map(item => item + 1); console.log(a, b); // [1,32, 442, 234] [2, 33, 443, 235]
undefined
var a = [1, 32, 442, 234]; c = a.map(() => {}); console.log(c); // [ undefined, undefined, undefined, undefined ]
d = a.map((item, i) => { console.log(i); // 0,1,2,3 });
e = a.map((item, i, array) => { console.log(array); // 最後會打印四遍 [1,34,442,234] })
以上不改變原數組的函數若是結果須要屢次使用,最好都定義一個新的變量來存儲。
讓我看一個簡短的filter,是否是有一種四兩撥千斤的感受。
var a = [{ flag: false, name: 'lihua' }, { flag: true, name: 'zengcuo' }]; console.log(a.filter(item => item.flag)); // [{flag:true,name:'zengcuo'}]
let arr = [1, 2, 3]; console.log(arr.reduce((pre, next) => pre + next)); // 6
var people = ['crimeA', 'crimeB']; console.log(people.some(item => item.indexOf('crimeA') > -1)); // true 只要有罪行A 就返回 true console.log(people.every(item => item.indexOf('crimeA')> -1)); // false 每一個數組都要 罪行A 才返回 true
Array.from:從一個相似數組或可迭代的對象中建立一個新的數組
能夠用來做數組去重
let arr = [1, '11', '11', 1, 8,]; let res = Array.from(new Set(arr)); console.log(res); // [1, '11', 8]
Array.fill(target, start, end):用一個固定的值填充一個數組
能夠用來快速的繁殖數組
let arr = new Array(3); let obj = {a: 1}; arr.fill(obj); console.log(arr); // [ { a: 1 }, { a: 1 }, { a: 1 } ]
complete.