<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Javascript一維數(shù)組和對(duì)象數(shù)組排序方案

          共 3370字,需瀏覽 7分鐘

           ·

          2020-11-17 02:51


          作者:Wonfody

          來源:SegmentFault 思否




          一、普通一維數(shù)組


          js中用 sort()?方法為數(shù)組排序。sort()?方法有一個(gè)可選參數(shù),是用來確定元素順序的函數(shù)。如果這個(gè)參數(shù)被省略,那么數(shù)組中的元素將按照ASCII字符順序進(jìn)行排序。如:


          var arr = ["a", "A", "c", "B"];arr.sort();console.log(arr); // ["A", "B", "a", "c"]

          注意:sort()?方法在在原數(shù)組上進(jìn)行排序,不生成副本。


          因?yàn)樽帜窤、B的ASCII值分別為65、66,而a、b的值分別為97、99,所以上面輸出的結(jié)果是?["A", "B", "a", "c"]?。


          如果數(shù)組元素是數(shù)字呢,結(jié)果會(huì)是怎樣?


          var arr = [15, 8, 25, 3];arr.sort();console.log(arr); // [15, 25, 3, 8]


          結(jié)果是?[15, 25, 3, 8]?。其實(shí),sort方法會(huì)調(diào)用每個(gè)元素的 toString()?方法,得到字符串,然后再對(duì)得到的字符串進(jìn)行排序。雖然數(shù)值15比3大,但在進(jìn)行字符串比較時(shí)"15"則排在"3"前面。顯然,這種結(jié)果不是我們想要的,這時(shí),sort()?方法的參數(shù)就起到了作用,我們把這個(gè)參數(shù)叫做比較函數(shù)。


          比較函數(shù)接收兩個(gè)參數(shù),如果第一個(gè)參數(shù)應(yīng)該位于第二個(gè)之前則返回一個(gè)負(fù)數(shù),如果第一個(gè)參數(shù)應(yīng)該位于第二個(gè)之后則返回一個(gè)正數(shù),如果兩個(gè)參數(shù)相等則返回0。例子:


          var arr = [23, 9, 4, 78, 3];
          // 比較函數(shù)var compare = function (x, y) { if (x < y) { return -1; } else if (x > y) { return 1; } else { return 0; }}console.log(arr.sort(compare));


          結(jié)果為?[3, 4, 9, 23, 78]?,返回了我們想要的結(jié)果。如果要按降序排序,比較函數(shù)寫成這樣即可:


          var compare = function (x, y) {    if (x < y) {        return 1;    } else if (x > y) {        return -1;    } else {        return 0;    }}


          我們并不能用比較函數(shù)比較一個(gè)不能轉(zhuǎn)化為數(shù)字的字符串與數(shù)字的順序:


          var arr = ["b", 5];console.log(arr.sort(compare))


          結(jié)果是?["b", 5]?。因?yàn)楸容^函數(shù)在比較時(shí),會(huì)把先把字符串轉(zhuǎn)化為數(shù)字,然后再比較,字符串b不能轉(zhuǎn)化為數(shù)字,所以就不能比較大小。然而,當(dāng)不用比較函數(shù)時(shí),會(huì)比較ASCII值,所以結(jié)果是?[5, "b"]?。




          二、數(shù)組對(duì)象


          如果數(shù)組項(xiàng)是對(duì)象,我們需要根據(jù)數(shù)組項(xiàng)的某個(gè)屬性對(duì)數(shù)組進(jìn)行排序,要怎么辦呢?其實(shí)和前面的比較函數(shù)也差不多:


          var arr = [{name: "zlw", age: 24}, {name: "wlz", age: 25}];var compare = function (obj1, obj2) {    var val1 = obj1.name;    var val2 = obj2.name;    if (val1 < val2) {        return -1;    } else if (val1 > val2) {        return 1;    } else {        return 0;    }            } console.log(arr.sort(compare));


          輸出結(jié)果為?[{ name="wlz", age=25}, { name="zlw", age=24}]?,可以看到數(shù)組已經(jīng)按照 name 屬性進(jìn)行了排序。我們可以對(duì)上面的比較函數(shù)再改造一下:


          var compare = function (prop) {    return function (obj1, obj2) {        var val1 = obj1[prop];        var val2 = obj2[prop];        if (val1 < val2) {            return -1;        } else if (val1 > val2) {            return 1;        } else {            return 0;        }                } }


          如果想按照 age 進(jìn)行排序,arr.sort(compare("age"))?即可。


          但是對(duì)age屬性進(jìn)行排序時(shí)需要注意了,如果age屬性的值是數(shù)字,那么排序結(jié)果會(huì)是我們想要的。但很多時(shí)候我們從服務(wù)器傳回來的數(shù)據(jù)中,屬性值通常是字符串。現(xiàn)在我把上面的數(shù)組改為:


          var arr = [{name: "zlw", age: "24"}, {name: "wlz", age: "5"}];

          可以看到,我把 age 屬性由數(shù)字改為了字符串,第二個(gè)數(shù)組項(xiàng)的 age 值改為了?"5"?。再次調(diào)用 arr.sort(compare("age"))?后,結(jié)果為:

          [Object?{?name="zlw",?age="24"},?Object?{?name="wlz",?age="5"}]


          我們的期望是5排在24前面,但是結(jié)果不是。這是因?yàn)楫?dāng)兩個(gè)數(shù)字字符串比較大小時(shí),會(huì)比較它們的ASCII值大小,比較規(guī)則是:從第一個(gè)字符開始,順次向后直到出現(xiàn)不同的字符為止,然后以第一個(gè)不同的字符的ASCII值確定大小。所以"24"與"5"比較大小時(shí),先比較”2“與"5"的ASCII值,顯然”2“的ASCII值比"5"小,即確定排序順序。


          現(xiàn)在,我們需要對(duì)比較函數(shù)再做一些修改:


          var compare = function (prop) {    return function (obj1, obj2) {        var val1 = obj1[prop];        var val2 = obj2[prop];        if (!isNaN(Number(val1)) && !isNaN(Number(val2))) {            val1 = Number(val1);            val2 = Number(val2);        }        if (val1 < val2) {            return -1;        } else if (val1 > val2) {            return 1;        } else {            return 0;        }                } }


          在比較函數(shù)中,先把比較屬性值轉(zhuǎn)化為數(shù)字 Number(val1)?再通過 !isNaN(Number(val1))?判斷轉(zhuǎn)化后的值是不是數(shù)字(有可能是NaN),轉(zhuǎn)化后的值如果是數(shù)字,則比較轉(zhuǎn)換后的值,這樣就可以得到我們想要的結(jié)果了, 調(diào)用 arr.sort(compare("age"))?得到:


          [Object { name="wlz", age="5"}, Object { name="zlw", age="24"}]


          可以看到,確實(shí)是按正確的方式排序了。


          參考:

          https://www.cnblogs.com/xljzlw/p/3694861.html





          點(diǎn)擊左下角閱讀原文,到?SegmentFault 思否社區(qū)?和文章作者展開更多互動(dòng)和交流。

          -?END -

          瀏覽 24
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚卅毛片 | 欧美性爱手机在线 | 草肉肉XXXXHD劉亦菲 | 天天摸天天操视频 | 免费无码又爽又黄又刺激网站 |