JavaScript物件存在陣列裡的搜尋方法

JavaScript在一般的陣列中,可以直接使用filter、map來遍歷元素並搜尋或取得資料
但在object,就無法使用這些方便的函式了!
尤其當資料內容又是以物件型式儲存在陣列裡面
兩個東西結合在一起的時候真的是會寫到一團亂不知道自己在寫什麼東西XD
花了不少時間總算寫了個應該….還算是精簡的寫法QQ

需求:在一個搜尋框輸入關鍵字,可搜尋表格內的每一欄位,並即時呈現結果

[> DEMO <](https://codepen.io/windclara/pen/MraYRZ?editors=1010)

由於我來源資料是儲存在nedb裡面(註:nedb為一輕量化的單機版mongoDB,可視為nosql版的sqlite)

nedb中每一筆資料是一個物件,查詢出來後的所有結果回傳成一組陣列
就會得到如下的資料結構:

dbData = [
 {id:0001,name:'王小明',phone:0912345678},
 {id:0002,name:'劉得滑',phone:0987654321},
 {id:0003,name:'周潤花',phone:0978123456},
 {id:0004,name:'林志零',phone:0955111222}];

搜尋功能的程式碼:

function search(searchValue){
    let searched = dbData.map(obj => {
        if ( Object.keys(obj).some( property => obj[property].toString().indexOf(searchValue) != -1 ) )
          return obj;
      });
      return searched.filter(obj => obj != undefined);
}
//demo網頁我使用vue,所以demo網頁裡的寫法會略有不同
//為方便您使用,文中以function呈現

說明:

  1. 用陣列提供的map函式,遍歷出每筆資料
  2. 由於object無map、filter函式,使用Object.keys取得object裡的每個property以遍歷每一object裡的內容。而Object提供some函式,只要其中一筆內容符合則回傳true
  3. 接著使用obj[property] 取得該物件屬性內的值。會得到:0001,王小明,0912345678,0002,劉得滑….等每一property裡的值。
  4. 將資料內容轉換成字串,使用indexOf判斷是否符合,若符合則回傳整個物件
  5. 將searchValue console.log出來的話,會發現是一陣列包含符合條件的物件,不符合條件的則回傳undefined。得到內容長這樣(以搜尋王小明為例)
    [{id:0001,name:'王小明',phone:0912345678},undefined,undefined,undefined]
    //資料內容總長有幾筆不合條件,就會有幾個undefined
  6. 最後在用filter 過濾掉undefined,就可以得到我們想要的結果!

參考資料

JavaScript取出陣列重複/不重複值的方法
Quickly filter an object by keys