Javascript一維數組和對象數組排序方案

1、普通一維數組

js中用 sort() 方法爲數組排序。sort() 方法有一個可選參數,是用來肯定元素順序的函數。若是這個參數被省略,那麼數組中的元素將按照ASCII字符順序進行排序。如:javascript

var arr = ["a", "A", "c", "B"];
arr.sort();
console.log(arr); // ["A", "B", "a", "c"]
注意: sort() 方法在在原數組上進行排序,不生成副本。

由於字母A、B的ASCII值分別爲6五、66,而a、b的值分別爲9七、99,因此上面輸出的結果是 ["A", "B", "a", "c"]html

若是數組元素是數字呢,結果會是怎樣?java

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

結果是 [15, 25, 3, 8] 。其實,sort方法會調用每一個元素的 toString() 方法,獲得字符串,而後再對獲得的字符串進行排序。雖然數值15比3大,但在進行字符串比較時"15"則排在"3"前面。顯然,這種結果不是咱們想要的,這時,sort() 方法的參數就起到了做用,咱們把這個參數叫作比較函數。windows

比較函數接收兩個參數,若是第一個參數應該位於第二個以前則返回一個負數,若是第一個參數應該位於第二個以後則返回一個正數,若是兩個參數相等則返回0。例子:數組

var arr = [23, 9, 4, 78, 3];

// 比較函數
var compare = function (x, y) {
    if (x < y) {
        return -1;
    } else if (x > y) {
        return 1;
    } else {
        return 0;
    }
}
console.log(arr.sort(compare));

結果爲 [3, 4, 9, 23, 78] ,返回了咱們想要的結果。若是要按降序排序,比較函數寫成這樣便可:服務器

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

咱們並不能用比較函數比較一個不能轉化爲數字的字符串與數字的順序:函數

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

結果是 ["b", 5] 。由於比較函數在比較時,會把先把字符串轉化爲數字,而後再比較,字符串b不能轉化爲數字,因此就不能比較大小。然而,當不用比較函數時,會比較ASCII值,因此結果是 [5, "b"]code

2、數組對象

若是數組項是對象,咱們須要根據數組項的某個屬性對數組進行排序,要怎麼辦呢?其實和前面的比較函數也差很少:htm

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));

輸出結果爲 [{ name="wlz", age=25}, { name="zlw", age=24}] ,能夠看到數組已經按照 name 屬性進行了排序。咱們能夠對上面的比較函數再改造一下:對象

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 進行排序,arr.sort(compare("age")) 便可。

可是對age屬性進行排序時須要注意了,若是age屬性的值是數字,那麼排序結果會是咱們想要的。但不少時候咱們從服務器傳回來的數據中,屬性值一般是字符串。如今我把上面的數組改成:

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

能夠看到,我把 age 屬性由數字改成了字符串,第二個數組項的 age 值改成了 "5" 。再次調用 arr.sort(compare("age")) 後,結果爲:

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

咱們的指望是5排在24前面,可是結果不是。這是由於當兩個數字字符串比較大小時,會比較它們的ASCII值大小,比較規則是:從第一個字符開始,順次向後直到出現不一樣的字符爲止,而後以第一個不一樣的字符的ASCII值肯定大小。因此"24"與"5"比較大小時,先比較」2「與"5"的ASCII值,顯然」2「的ASCII值比"5"小,即肯定排序順序。

如今,咱們須要對比較函數再作一些修改:

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;
        }            
    } 
}

在比較函數中,先把比較屬性值轉化爲數字 Number(val1) 再經過 !isNaN(Number(val1)) 判斷轉化後的值是否是數字(有多是NaN),轉化後的值若是是數字,則比較轉換後的值,這樣就能夠獲得咱們想要的結果了, 調用 arr.sort(compare("age")) 獲得:

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

能夠看到,確實是按正確的方式排序了。

以上內容參考: https://www.cnblogs.com/xljzl...

3、排序混合的字母/數字數組

前面咱們都已瞭解數組中的元素將按照ASCII字符順序進行排序,數組中元素爲字母與數字混合時,正常排序是這樣的:

var arr = ["a11", "C", "a2", "C4", "C33"];
arr.sort();
console.log(arr); // ["C", "C33", "C4", "a11", "a2"]

咱們發現 C33 在 C4 的前面,a11 在a2的前面,可能這種排序方式不能知足一些需求,若是咱們的需求是這樣:前面字母相同的狀況下,後面根據數字的大小來排序。如上面的例子要排成 ["C", "C4", "C33", "a2", "a11"] 這樣的結果,咱們就須要用到正則了,能夠這樣來實現:

var reA = /[^a-zA-Z]/g;
var reN = /[^0-9]/g;

function sortAlphaNum(a, b) {
    var aA = a.replace(reA, "");
    var bA = b.replace(reA, "");
    if (aA === bA) {
        var aN = parseInt(a.replace(reN, ""), 10);
        var bN = parseInt(b.replace(reN, ""), 10);
        return aN === bN ? 0 : aN > bN ? 1 : -1;
    } else {
        return aA > bA ? 1 : -1;
    }
}

var arr = ["A1", "A10", "A11", "A12", "A2", "A3", "A4", "B10", "B2", "F1", "F12", "F3"];
arr.sort(sortAlphaNum); // ["A1", "A2", "A3", "A4", "A10", "A11", "A12", "B2", "B10", "F1", "F3", "F12"]

對象數組的實現方案也是相似,只是須要添加須要排序的key名:

var reA = /[^a-zA-Z]/g;
var reN = /[^0-9]/g;

function sortAlphaNum(a, b) {
    var aA = a.name.replace(reA, "");
    var bA = b.name.replace(reA, "");
    if (aA === bA) {
        var aN = parseInt(a.name.replace(reN, ""), 10);
        var bN = parseInt(b.name.replace(reN, ""), 10);
        return aN === bN ? 0 : aN > bN ? 1 : -1;
    } else {
        return aA > bA ? 1 : -1;
    }
}

var singers = [
  { name: 'Ttevie Nicks', band: 'Fleetwood Mac', born: 1948 },
  { name: 'Steven Tyler101', band: 'Aerosmith', born: 1948 },
  { name: 'Steven Tyler11', band: 'The Carpenters', born: 1950 },
  { name: 'Kurt Cobain', band: 'Nirvana', born: 1967 },
  { name: 'Stevie Nick', band: 'Fleetwood Mac', born: 1948 },
  { name: 'Stevie Nicks', band: 'Fleetwood Mac', born: 1948 },
  { name: 'Kurt Coba35in', band: 'Nirvana', born: 1967 },
  { name: 'Kurt Cobai35n', band: 'Nirvana', born: 1967 },
];

console.log(singers.sort(sortAlphaNum));
// 輸出結果
// [
//     {name: "Kurt Coba35in", band: "Nirvana", born: 1967}
//     1: {name: "Kurt Cobai35n", band: "Nirvana", born: 1967}
//     2: {name: "Kurt Cobain", band: "Nirvana", born: 1967}
//     3: {name: "Steven Tyler11", band: "The Carpenters", born: 1950}
//     4: {name: "Steven Tyler101", band: "Aerosmith", born: 1948}
//     5: {name: "Stevie Nick", band: "Fleetwood Mac", born: 1948}
//     6: {name: "Stevie Nicks", band: "Fleetwood Mac", born: 1948}
//     7: {name: "Ttevie Nicks", band: "Fleetwood Mac", born: 1948}
// ]

對上面的對比函數進行改造:

var sortAlphaNum = function (key) {
    return function (a, b) {
        var aA = a[key].replace(reA, "");
        var bA = b[key].replace(reA, "");
        if (aA === bA) {
            var aN = parseInt(a[key].replace(reN, ""), 10);
            var bN = parseInt(b[key].replace(reN, ""), 10);
            return aN === bN ? 0 : aN > bN ? 1 : -1;
        } else {
            return aA > bA ? 1 : -1;
        }
    }
}

能夠直接指定key進行排序:

singers.sort(sortAlphaNum('name'));
這種排序方式和windows文件名/文件夾排序方式基本相同
相關文章
相關標籤/搜索