Lodash 這個函式庫中,提供了高達上百種的方法,有些方法可以說是原生 JavaScript 的加強版,或是將原有的原型方法包裝成純函式。
除了在實務開發時,可以透過 Lodash 解決一些需要複雜運算才可以解決的問題,同時也可以透過 Lodash 所提供的方法,了解 JavaScript 的特性與進階用法,可以說是一個非常值得效仿學習的函式庫。
在這個章節中,我們要來聊聊,Lodash 提供哪些好用的 API ,讓我們可以簡化前端的複雜任務。
以下範例會主要會以 CDN 的方式進行程式碼的示範,若是想了解如何使用 UMD 的方式引入 Lodash,可以參考前面的章節,那就讓我們來看看 Lodash 中有哪些好用的方法吧!
filter
方法搭配進行條件篩選:試想一個狀況,我們想要針對一個後台表單的內容進行複雜篩選,例如:後台管理者可以透過關鍵字搜尋,查找出指定的那一筆資料,如果我們要透過 JavaScript 來做到這件事,光是想就相當複雜,但如果是透過 Lodash 提供的 filter
方法,可以很快速的做到篩選的功能!
Lodash 所提供的 filter
方法其實與原生 JavaScript 的 filter
方法差異不大,原生的 filter 是使用串接的方式:
const ary = [1, 2, 3, 4, 5];
const filterAry = ary.filter(i => i> 2);
console.log(filterAry);
// [3, 4, 5]
而 Lodash 所提供的 filter()
方法,是基於 FP 設計模式,所以是使用帶入參數的方式使用,第一個參數帶入要進行篩選的陣列,第二個參數則是帶入進行條件篩選的 callback 函式:
const ary = [1, 2, 3, 4, 5];
const filterAry = _.filter(ary, i => i> 2);
console.log(filterAry);
// [3, 4, 5]
除了可以照原生的方式來使用 filter()
方法,Lodash 還為這個函式延伸出更多強大的功能,透過在第二個參數傳入物件、陣列或是字串來進行陣列的篩選,讓我們來看看以下範例:
const list = [
{
name: '王小明',
},
{
name: '張小美',
}
];
const filterByObj = _.filter(list, {name: '王小明'});
console.log(filterByObj);
const filterByAry = _.filter(list, ['name','王小明']);
console.log(filterByAry);
const filterByStr = _.filter(list, 'name');
console.log(filterByStr);
/*
output 1 & 2:
[{
name: '王小明',
},
]
output 3:
[
{
name: '王小明',
},
{
name: '張小美',
}
];
*/
當在 Lodash filter()
方法第二個參數傳入:
JSON.Stringify()
字串化之排列順序一致 ),若有相同即將該迭代中的物件回傳至新陣列中。如果想要找到符合第一筆就停止資料的查找,我們還可以透過 Lodash 所提供的 find
方法來提升資料查找的效能,其使用方法與上述 filter
方法相同。
在以往的 FP 中,我們可以透過 filter 方法篩選我們所要的資料,來做到刪除特定資料的目的,但在 Lodash 中我們可以直接使用 reject
這個方法來達到相同的目標。
sorted
系列方法加快排序演算在建置一些後台服務時,為了避免頻繁的呼叫 API 佔到自家後端的效能,有時我們可能會將排序的邏輯寫在前端頁面上,如此一來前端進行篩選或是排序的程式碼效能就會變得相當重要。
Lodash 提供一系列以 sorted
開頭的方法,讓我們可以透過二分搜尋法(binary search,請見註一)的方式優化排序的時間複雜度(註二),舉例來說,我們可以透過 sortedUniq
方法篩選陣列中的不重複純值。
const ary = ['王小明', '王小明', '張小花', '林小白'];
const sorted = _.sortedUniq(ary);
console.log(sorted);
// ["王小明","張小花","林小白"]
partition
方法條件式分類陣列在 Lodash 中有提供許多將陣列進行展開、分類的方法,我們可以透過 partition
方法將陣列進行條件式的切割分類,使用的方式與 fitler
方法幾乎一樣,我們會在第二個參數中帶入篩選條件,這個條件可以是 callback function、物件、陣列或是字串。
這個方法會將符合條件的內容,封裝進陣列中,並作為另一個新陣列中的第一筆資料,不符合條件的則會封裝進另一個陣列,作為另一個新陣列中的第二筆資料:
const members = [
{
name: '王小明',
verify: false,
},
{
name: '張小花',
verify: false,
},
{
name: '林小白',
verify: true,
},
];
const groupedByCallback = _.partition(members, ({verify}) => !verify);
console.log(groupedByCallback);
/*
[
[
{
name: '王小明',
verify: false,
},
{
name: '張小花',
verify: false,
},
],
[
{
name: '林小白',
verify: true,
},
],
]
*/
個人認為 partition
方法非常好用,當需要進行同一資料的重複分類時,我們可以同時取到屬於、不屬於指定條件的資料,然後分別進行更進階的篩選,這樣就不用針對對一資料重複跑迴圈了。
flat
系列方法攤平資料結構在先前的章節中,我們曾透過 JavaScript 中的 reduce()
陣列方法來攤平,或是依照自己的開發需求重整資料結構,但如果不想要這麼麻煩自己重寫一個,可以透過 Lodash 協助我們做到這件事:
const flattenAry = _.flatten([1, [2, [3, [4]], 5]]);
console.log(flattenAry);
// => [1, 2, [3, [4]], 5]
在上方的範例中,我們在 flatten()
函式中,傳入了多層級的的陣列,經過處理後,內部的階層被拆掉了一層,Lodash 函式庫提供了許多類似的方法,讓開發者可針對不同的資料結構進行淺層、深層的攤平。
is
系列方法檢查資料型別在 JavaScript 中,「自動轉型」大概是最煩人的問題之一,如果我們想要檢查指定資料的型別,光靠 typeof()
運算子是沒有辦法獲得所有精準的型別,但我們可以透過 Lodash 做到許多型別的檢查:
// 在 JavaScript 中使用 typeof() 檢查 Date 型別的話,會印出 'object' 字串
typeof(new Date);
// => 'object'
const isDate1 = _.isDate(new Date);
console.log(isDate1);
// => true
const isDate2 = _.isDate('Mon April 23 2012');
console.log(isDate2);
// => false
舉例來說,我們可以透過 isDate()
方法檢查指定的資料是否為 Date
型別。
或是我們可以透過 isBoolean()
檢查某資料的型別是否為布林值:
const isBool1 = _.isBoolean(false);
console.log(isBool1);
// => true
const isBool2 = _.isBoolean(null);
console.log(isBool2);
// => false
Lodash 函式庫中提供了許多方便且能快速上手的工具方法,但如果你是一個柯里愛好者的話,另外一個函式庫也許會更對你的胃,在下一個章節中,我們要來介紹另外一個同樣知名的 FP 函式庫,那我們就下一個章節見啦!
// *O(1):用 notation 一次找到我們所需要的值
const target1 = ary[0];
const target2 = obj.key;
const target3 = obj[key]*
// *O(n):透過迴圈進行遍歷查找
let target4Index;
ary.forEach((item, index) => {
if(item === '小明') target4Index = index;
});
// O(n^2):迴圈中再包裹迴圈遍歷查找
let target5Index;
ary.forEach( innerAry => {
innerAry.forEach((item, index) => {
if(item === '小明') target5Index = index;
});
// O(log n) 可快速透過 Lodash 函式庫做到
const target6Index = _.sortedIndexOf([4, 5, 5, 5, 6], 5);
console.log(target6Index)
// 1*