[javascript]處理陣列 Lazy.js vs Linq.js vs lodash的比較

前端方便處理複雜陣列的library比較

前言

 

最近因為有一個專案,需要在前端處理很複雜的viewmodel,所以在尋找前端方便的library,可以做類似linq在處理的事情,相信寫mvc的人對linq和lambda也非常熟悉了,如果有人還是把orm當成是來取代sql的觀念,請快點改正您的觀念,雖然有人會使用原始的javascript來處理這種需求,但是因為原生對陣列或對象的處理並沒有提供如此多的功能,在前端的世界裡面,目前就以lodash最為知名,而.net的大多數人則會選擇使用linq.js來延續即有的知識,來處理前端陣列的處理,而我又另外找了一個lazy.js的library,接著我就要來寫明一些需求,還有比較三種library的寫法,還有效能的比較。

 

複雜對象的巢狀陣列

 

在此我建了一個4*4*4的巢狀對象,展開之後就會是四個legs四個ekis四個directoin,程式碼如下


                'mainOptionLegs': [{
                    'ekis': [{
                        'direction': 1
                    }, {
                        'direction': 2
                    }, {
                        'direction': 3
                    }, {
                        'direction': 4
                    }]
                }, {
                    'ekis': [{
                        'direction': 1
                    }, {
                        'direction': 2
                    }, {
                        'direction': 3
                    }, {
                        'direction': 4
                    }]
                }, {
                    'ekis': [{
                        'direction': 1
                    }, {
                        'direction': 2
                    }, {
                        'direction': 3
                    }, {
                        'direction': 4
                    }]
                }, {
                    'ekis': [{
                        'direction': 1
                    }, {
                        'direction': 2
                    }, {
                        'direction': 3
                    }, {
                        'direction': 4
                    }]
                }]
            }, {
                'mainOptionLegs': [{
                    'ekis': [{
                        'direction': 1
                    }, {
                        'direction': 2
                    }, {
                        'direction': 3
                    }, {
                        'direction': 4
                    }]
                }, {
                    'ekis': [{
                        'direction': 1
                    }, {
                        'direction': 2
                    }, {
                        'direction': 3
                    }, {
                        'direction': 4
                    }]
                }, {
                    'ekis': [{
                        'direction': 1
                    }, {
                        'direction': 2
                    }, {
                        'direction': 3
                    }, {
                        'direction': 4
                    }]
                }, {
                    'ekis': [{
                        'direction': 1
                    }, {
                        'direction': 2
                    }, {
                        'direction': 3
                    }, {
                        'direction': 4
                    }]
                }]
            }, {
                'mainOptionLegs': [{
                    'ekis': [{
                        'direction': 1
                    }, {
                        'direction': 2
                    }, {
                        'direction': 3
                    }, {
                        'direction': 4
                    }]
                }, {
                    'ekis': [{
                        'direction': 1
                    }, {
                        'direction': 2
                    }, {
                        'direction': 3
                    }, {
                        'direction': 4
                    }]
                }, {
                    'ekis': [{
                        'direction': 1
                    }, {
                        'direction': 2
                    }, {
                        'direction': 3
                    }, {
                        'direction': 4
                    }]
                }, {
                    'ekis': [{
                        'direction': 1
                    }, {
                        'direction': 2
                    }, {
                        'direction': 3
                    }, {
                        'direction': 4
                    }]
                }]
            }, {
                'mainOptionLegs': [{
                    'ekis': [{
                        'direction': 1
                    }, {
                        'direction': 2
                    }, {
                        'direction': 3
                    }, {
                        'direction': 4
                    }]
                }, {
                    'ekis': [{
                        'direction': 1
                    }, {
                        'direction': 2
                    }, {
                        'direction': 3
                    }, {
                        'direction': 4
                    }]
                }, {
                    'ekis': [{
                        'direction': 1
                    }, {
                        'direction': 2
                    }, {
                        'direction': 3
                    }, {
                        'direction': 4
                    }]
                }, {
                    'ekis': [{
                        'direction': 1
                    }, {
                        'direction': 2
                    }, {
                        'direction': 3
                    }, {
                        'direction': 4
                    }]
                }]
            }];

 

如果今天我想要把所有direction都改成5的話,就來看看各種寫法的差異吧。

 

程式碼比較

 

linq.js

 

相信熟悉lambda的人,幾乎沒有任何學習成本就能上手linq.js,非常簡單而且可讀性又好,如下程式碼


                .SelectMany(function(x) {
                    return x.mainOptionLegs;
                }).SelectMany(function(x) {
                    return x.ekis;
                }).ForEach(function(x) {
                    x.direction = 7;
                })

 

lodash

 

用lodash的概念跟linq.js有點不一樣,也就是我先選擇要select哪個值,然後在把四筆陣列變成一筆,對於熟悉linq的人可能會有點不習慣

 


                .pluck('mainOptionLegs')
                .flatten(function(x) {
                    return x;
                }).pluck('ekis')
                .flatten(function(x) {
                    return x;
                }).each(function(x) {
                    x.direction = 8;
                })

 

lazy.js

 

程式碼跟lodash大同小異,概念也都差不多,不過lodash使用的人多非常多,其實會lodash要轉換lazy.js也是沒什麼太大的問題

 


                .pluck('mainOptionLegs')
                .flatten(function(x) {
                    return x;
                }).pluck('ekis')
                .flatten(function(x) {
                    return x;
                }).each(function(x) {
                    x.direction = 5;
                })

 

效能比較

 

最後我測試做一樣的事情,最後完成的時間比較

 

image

 

結論

 

雖然在真實的前端世界,lodash不管是使用人數,或者是可google的資源多非常多,但經測試比較,lazy.js效能是最優秀的,而且因為兩者的觀念幾乎可以互通,所以我最後的選擇是使用lazy.js,如果到時候想轉換陣營,也能輕易的轉換,以上再請多多指教囉。