對 Array of Hash 做 Sort/Pagination

如果今天很不巧有一些設定不在 DB 而是在 yml 檔裡,不能用 model 操縱,拿出來的只有一個 array of hash,這時候要怎麼做 order/pagination/search/ 呢?

  1. 先做 search 假設你要搜尋的 string 叫做 filter,同時要找 idname 這兩個欄位
    filter = filter.downcase # 先轉小寫
    array_of_hash = array_of_hash.select {|hsh|
    hsh["col_1_id"].include?("#{filter}") ||
    hsh["col_2_name"].downcase.include?("#{filter}") # 通通用小寫比對
    }
    
  2. 再把搜尋結果排序 假設你要排序的欄位 叫做 order
    array_of_hash.map {|hsh| hsh["id"] = hsh["id"].to_i} #先把 id 轉成 integer 才會正確排序
    array_of_hash.sort_by! { |hsh| hsh["#{order}"] }
    
  3. 如果還要 descendent/ascendent 這裏假設傳進來的參數叫 desc,1 代表 desc,0 代表 asc,上面的 order 就要改為
    array_of_hash.sort_by! { |hsh| hsh["#{@order}"] }.reverse! if @desc == 1
    array_of_hash.sort_by! { |hsh| hsh["#{@order}"] } if @desc == 0
    
  4. 再做 pagination
    • 安裝 will_paginate
    • config/initalizers/ 底下新增一個檔案 config/initalizers/will_paginate_extensions.rb 裡面 require 'will_paginate/array' 這樣才可以對 array 做 pagination
    • 對剛才的 array_of_hash 做 pagination(注意,我剛才用的是 sort_by! 有個 ! 所以可以直接用 array_of_hash )
    • 一般 offset 從前端來的是 0,記得要加 1 回去

所以就會是

array_of_hash.paginate(page: offset, per_page: limit)

收工。

參考資料:
http://stackoverflow.com/questions/5483889/in-ruby-how-sort-an-array-of-hashes
http://stackoverflow.com/questions/13187076/paginating-an-array-in-ruby-with-will-paginate
http://stackoverflow.com/questions/2244915/how-do-i-search-within-an-array-of-hashes-by-hash-values-in-ruby