三泊碑、高階函數(shù) 一(map坤按、reduce、filter馒过、sort)


一臭脓、map

  • 映射,可以對(duì)數(shù)組中每個(gè)元素進(jìn)行操作,并逐一返回腹忽,生成一個(gè)理想的新數(shù)組
arr.map(function(item,index,arr){
    ..............
})
let arr1 = [1,4,9]
let newArr1 = arr1.map(Math.sqrt)       // Math.sqrt() 只接受一個(gè)參數(shù)来累, 所以默認(rèn)接受的是數(shù)組內(nèi)每一個(gè)元素
                                                             // 傳入對(duì)數(shù)組的每一個(gè)元素進(jìn)行開放 
console.log(newArr1);        //  [1,2,3]
//返回對(duì)象中指定的字段砚作,組成新數(shù)組 (可以將數(shù)組的id挑選出來)
let arr4 = [{a:1,x:2},{a:2,x:2},{a:3,x:2}]
let newArr4 = arr4.map(item => item.a)
console.log(newArr4);        //[1, 2, 3]
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
arr.map(String); // ['1', '2', '3', '4', '5', '6', '7', '8', '9']
  • 備注:map的回調(diào)函數(shù)中不能使用判斷語句 (使用的話只能返回 boolean 值),必須直接return嘹锁,否則會(huì)返回undefined葫录。但是可以返回boolean值
  let arr4 = [
        { a: 1, x: 2 },
        { a: 2, x: 2 },
        { a: 3, x: 2 }
      ]
let newArr4 = arr4.map(item => item.a > 1)
console.log(newArr4) //  [false, true, true]

二、reduce

  • 接收一個(gè)函數(shù)作為累加器(accumulator)领猾,數(shù)組中的每個(gè)值(從左到右)開始合并米同,最終為一個(gè)值。
  • callback(執(zhí)行數(shù)組中每個(gè)值的函數(shù)摔竿,包含四個(gè)參數(shù))
  • previousValue(上一次調(diào)用回調(diào)函數(shù)返回的值面粮,或者是提供的初始值(initialValue))
  • currentValue(數(shù)組中當(dāng)前被處理的元素)
  • index(當(dāng)前元素在數(shù)組中的索引)
  • array(調(diào)用reduce的數(shù)組)

reduce可以傳一個(gè)初始值,也可以不傳继低,直接熬苍,將previousValue當(dāng)做初始值
初始值可以傳任何類型的值

// 不傳遞初始值,直接以數(shù)組內(nèi)的第一個(gè)元素為初始值袁翁。沒傳遞初始值時(shí)柴底,第一個(gè)參數(shù)就是上一次回調(diào)返回的值,這里的init依次是:1   3   6
      // 累加arr的值
      let arr = [10, 20, 30, 40]
      let total = arr.reduce((pre, value, index, arr) => {
        console.log(pre) // 10, 20, 40, 70 (有初始化值 10)
        // console.log(pre) // 10, 30, 60, 100 (無初始化值)
        return pre + value
      })
      console.log(total)

// data 為10

// 傳遞一個(gè)Number初始值梦裂,
//init第一次是初始值10似枕,之后每次都是上一次回調(diào)函數(shù)返回的值:
     11    13    16
let arr = [1,2,3,4]
let data = arr.reduce((init,now) => {
    return init+now
},10)
//data為20

//傳遞一個(gè)Object初始值.  使對(duì)象里的屬性和某數(shù)組內(nèi)的元素累加
let arr = [1,2,3,4]
let data = arr.reduce((init,now) => {
    init.sum = init.sum + now
    return init
},{sum:2})
console.log(data);  // {sum:12}

//對(duì)象內(nèi)的某個(gè)屬性進(jìn)行累加
let arr = [
    {a:1,name:'a'},
    {a:2,name:'b'},
    {a:3,name:'c'},
]
let data = arr.reduce((init,now) => {
    return init + now.a
},0)
console.log(data);    // 6

//  查看某字符串,每個(gè)字符出現(xiàn)的次數(shù)
var str = 'abccacbbaacaa'
var obj = str.split('').reduce((init,now) => {
init[now] ? ++init[now] : init[now] = 1
return init
},{})
console.log(obj); //{a: 6, b: 3, c: 4}
  • 再看reduce的用法年柠。Array的reduce()把一個(gè)函數(shù)作用在這個(gè)Array的[x1, x2, x3...]上,這個(gè)函數(shù)必須接收兩個(gè)參數(shù)褪迟,reduce()把結(jié)果繼續(xù)和序列的下一個(gè)元素做累積計(jì)算冗恨,其效果就是:
[x1, x2, x3, x4].reduce(f) = f(f(f(x1, x2), x3), x4)
  • 比方說對(duì)一個(gè)Array求和,就可以用reduce實(shí)現(xiàn):
var arr = [1, 3, 5, 7, 9];
arr.reduce(function (x, y) {
    return x + y;
}); // 25
  • 計(jì)數(shù)值大于2的有幾個(gè)
     let arr = [1, 2, 3, 4]
      let total = arr.reduce((pre, value, index, arr) => {

        if (value > 2) {
          return pre + 1
        }
        return pre
      }, 0)
      console.log(total)

三味赃、filter

  • filter也是一個(gè)常用的操作掀抹,它用于把Array的某些元素過濾掉躁染,然后返回剩下的元素店诗。

  • 和map()類似搞旭,Array的filter()也接收一個(gè)函數(shù)至耻。和map()不同的是破加,filter()把傳入的函數(shù)依次作用于每個(gè)元素剧防,然后根據(jù)返回值是true還是false決定保留還是丟棄該元素旦装。

  • 例如笛坦,在一個(gè)Array中狠持,刪掉偶數(shù)疟位,只保留奇數(shù),可以這么寫:
    ···
    //過濾掉數(shù)組中不符合的元素

let arr = [1,2,3]
let newArr = arr.filter((item) => item > 1)

// 過濾掉數(shù)組中空項(xiàng)喘垂,轉(zhuǎn)為布爾為false的元素

let arr = [1,'',undefined,2,3]
let newArr = arr.filter(item => item)

// 過濾掉數(shù)組內(nèi)不符合條件的對(duì)象

let arr = [{a:1},{a:2},{a:3}]
let newArr = arr.filter(item => item.a > 1)
console.log(newArr);    // [{a:2},{a:3}]

//過濾掉指定的空項(xiàng)甜刻,將沒有x屬性的對(duì)象過濾掉

let arr = [{a:1,x:2},{b:1},{c:1,x:3}]
let newArr = arr.filter(item => item.x)
console.log(newArr);

// 數(shù)組去重

var arr = [1,2,3,1,2,5,4,3,3,1]
var newArr = arr.filter((item,index,arr)=>{
return arr.indexOf(item) === index
})
console.log(newArr)
  • 總結(jié): filter: 過濾出來當(dāng)前完整的元素绍撞。 map: 處理過的元素。如果是從一組元素中找出某個(gè)元素得院,用filter傻铣,如果對(duì)一組元素的子元素需要處理后返回,使用 map

四祥绞、sort

  • 排序也是在程序中經(jīng)常用到的算法矾柜。無論使用冒泡排序還是快速排序,排序的核心是比較兩個(gè)元素的大小就谜。如果是數(shù)字怪蔑,我們可以直接比較,但如果是字符串或者兩個(gè)對(duì)象呢丧荐?直接比較數(shù)學(xué)上的大小是沒有意義的缆瓣,因此,比較的過程必須通過函數(shù)抽象出來虹统。通常規(guī)定弓坞,對(duì)于兩個(gè)元素x和y,如果認(rèn)為x < y车荔,則返回-1渡冻,如果認(rèn)為x == y,則返回0忧便,如果認(rèn)為x > y族吻,則返回1,這樣珠增,排序算法就不用關(guān)心具體的比較過程超歌,而是根據(jù)比較結(jié)果直接排序。

  • JavaScript的Array的sort()方法就是用于排序的蒂教,但是排序結(jié)果可能讓你大吃一驚:

// 看上去正常的結(jié)果:
['Google', 'Apple', 'Microsoft'].sort(); // ['Apple', 'Google', 'Microsoft'];

// apple排在了最后:
['Google', 'apple', 'Microsoft'].sort(); // ['Google', 'Microsoft", 'apple']

// 無法理解的結(jié)果:
[10, 20, 1, 2].sort(); // [1, 10, 2, 20]
  • 第二個(gè)排序把a(bǔ)pple排在了最后巍举,是因?yàn)樽址鶕?jù)ASCII碼進(jìn)行排序,而小寫字母a的ASCII碼在大寫字母之后凝垛。

  • 第三個(gè)排序結(jié)果是什么鬼懊悯?簡單的數(shù)字排序都能錯(cuò)?

  • 這是因?yàn)锳rray的sort()方法默認(rèn)把所有元素先轉(zhuǎn)換為String再排序梦皮,結(jié)果'10'排在了'2'的前面炭分,因?yàn)樽址?1'比字符'2'的ASCII碼小。

  • 如果不知道sort()方法的默認(rèn)排序規(guī)則届氢,直接對(duì)數(shù)字排序欠窒,絕對(duì)栽進(jìn)坑里!

  • 幸運(yùn)的是,sort()方法也是一個(gè)高階函數(shù)岖妄,它還可以接收一個(gè)比較函數(shù)來實(shí)現(xiàn)自定義的排序型将。

var arr = [10, 20, 1, 2];
arr.sort(function (x, y) {
    if (x < y) {
        return -1;
    }
    if (x > y) {
        return 1;
    }
    return 0;
}); // [1, 2, 10, 20]
  • 如果要倒序排序,我們可以把大的數(shù)放前面:
var arr = [10, 20, 1, 2];
arr.sort(function (x, y) {
    if (x < y) {
        return 1;
    }
    if (x > y) {
        return -1;
    }
    return 0;
}); // [20, 10, 2, 1]
  • 默認(rèn)情況下荐虐,對(duì)字符串排序七兜,是按照ASCII的大小比較的,現(xiàn)在福扬,我們提出排序應(yīng)該忽略大小寫腕铸,按照字母序排序。要實(shí)現(xiàn)這個(gè)算法铛碑,不必對(duì)現(xiàn)有代碼大加改動(dòng)狠裹,只要我們能定義出忽略大小寫的比較算法就可以:

  • 默認(rèn)情況下,對(duì)字符串排序汽烦,是按照ASCII的大小比較的涛菠,現(xiàn)在,我們提出排序應(yīng)該忽略大小寫撇吞,按照字母序排序俗冻。要實(shí)現(xiàn)這個(gè)算法,不必對(duì)現(xiàn)有代碼大加改動(dòng)牍颈,只要我們能定義出忽略大小寫的比較算法就可以:

  • 忽略大小寫來比較兩個(gè)字符串迄薄,實(shí)際上就是先把字符串都變成大寫(或者都變成小寫),再比較煮岁。
    從上述例子可以看出讥蔽,高階函數(shù)的抽象能力是非常強(qiáng)大的,而且人乓,核心代碼可以保持得非常簡潔勤篮。最后友情提示,sort()方法會(huì)直接對(duì)Array進(jìn)行修改色罚,它返回的結(jié)果仍是當(dāng)前Array:

var a1 = ['B', 'A', 'C'];
var a2 = a1.sort();
a1; // ['A', 'B', 'C']
a2; // ['A', 'B', 'C']
a1 === a2; // true, a1和a2是同一對(duì)象
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市账劲,隨后出現(xiàn)的幾起案子戳护,更是在濱河造成了極大的恐慌,老刑警劉巖瀑焦,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腌且,死亡現(xiàn)場離奇詭異,居然都是意外死亡榛瓮,警方通過查閱死者的電腦和手機(jī)铺董,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人精续,你說我怎么就攤上這事坝锰。” “怎么了重付?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵顷级,是天一觀的道長。 經(jīng)常有香客問我确垫,道長弓颈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任删掀,我火速辦了婚禮翔冀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘披泪。我一直安慰自己纤子,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布付呕。 她就那樣靜靜地躺著计福,像睡著了一般。 火紅的嫁衣襯著肌膚如雪徽职。 梳的紋絲不亂的頭發(fā)上象颖,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音姆钉,去河邊找鬼说订。 笑死,一個(gè)胖子當(dāng)著我的面吹牛潮瓶,可吹牛的內(nèi)容都是我干的陶冷。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼毯辅,長吁一口氣:“原來是場噩夢啊……” “哼埂伦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起思恐,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤沾谜,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后胀莹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體基跑,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年描焰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了媳否。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖篱竭,靈堂內(nèi)的尸體忽然破棺而出力图,到底是詐尸還是另有隱情,我是刑警寧澤室抽,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布搪哪,位于F島的核電站,受9級(jí)特大地震影響坪圾,放射性物質(zhì)發(fā)生泄漏晓折。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一兽泄、第九天 我趴在偏房一處隱蔽的房頂上張望漓概。 院中可真熱鬧,春花似錦病梢、人聲如沸胃珍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽觅彰。三九已至,卻和暖如春钮热,著一層夾襖步出監(jiān)牢的瞬間填抬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國打工隧期, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留飒责,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓仆潮,卻偏偏與公主長得像宏蛉,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子性置,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348