Sort_by ใน Hash - ย้อนกลับหรือไม่ย้อนกลับ - อย่างไร

ฉันมีแฮชด้านล่าง:

library = {"1"=>{"title"=>"bbb", "money"=>10}, "2"=>{"title"=>"aaa", "money"=>12}}

และ application_helper.rb ของฉัน:

  def sortable_columns
    %w[title money]
  end

  def sort_column
    sortable_columns.include?(params[:column]) ? params[:column] : "title"
  end

  def sort_direction
    %w[asc desc].include?(params[:direction]) ? params[:direction] : "asc"
  end

  def sort_link(column, title)
    direction = column == sort_column && sort_direction == "asc" ? "desc" : "asc"
    icon = sort_direction == "asc" ? "fa fa-arrow-down" : "fa fa-arrow-up"
    icon = column == sort_column ? icon : ""
    link_to "#{title} <i class='#{icon}'></i>".html_safe, {column: column, direction: direction}
  end

ตารางของฉันใน table.html.erb:

          <table class="table table-striped">
            <thead>
            <tr>
                <th>#</th>
                <% sortable_columns.each do |column| %>
                  <th><%= sort_link column, column %></th>
                <% end %>
            </tr>
            </thead>
            <tbody>
              <% library.sort_by {|k| k[1][sort_column]}.each_with_index do |data, i| %>
               ...

              <% end %>
            </tbody>
          </table>

และตอนนี้ - หลังจากคลิกในส่วนหัว "ชื่อ" หรือ "เงิน" - ASC การเรียงลำดับของตาราง ฉันต้องการให้แสดง DESC เมื่อคลิกอีกครั้ง (พร้อมไอคอนลูกศรลง) สิ่งนี้สามารถทำได้อย่างไร? ฉันคิดถึง "ย้อนกลับ" หลังจาก library.sort_by {|k| k[1][sort_column]} แต่ไม่ได้ผล


person Kamil Pikula    schedule 21.05.2019    source แหล่งที่มา
comment
เนื่องจากไลบรารีทั้งหมดได้รับการเรนเดอร์ฝั่งไคลเอ็นต์ คุณเคยพิจารณาใช้หนึ่งในโซลูชันการเรียงลำดับตาราง JavaScript ที่มีอยู่หรือไม่   -  person Stefan    schedule 21.05.2019
comment
ไม่ ฉันไม่ได้พิจารณา คุณมีความคิดหรือไม่?   -  person Kamil Pikula    schedule 21.05.2019
comment
tablesorter หรือเปล่า คุณยังสามารถเขียนของคุณเองได้ โปรดดูการเรียงลำดับตาราง HTML ด้วย JavaScript   -  person Stefan    schedule 21.05.2019
comment
BTW เหตุใดคุณจึงใส่ข้อมูลลงในแฮชแทนที่จะเป็นตารางฐานข้อมูล จะดีกว่าไหมถ้าใช้ ActiveRecord เนื่องจากนี่เป็นคำถามของ Rails   -  person Stefan    schedule 21.05.2019
comment
@Stefan เพราะฉันได้รับข้อมูลจาก api ใน json และฉันไม่จำเป็นต้องเก็บไว้ในฐานข้อมูล วิธีของคุณใช้งานได้ แต่ฉันใช้วิธี tap ใน Ruby ขอบคุณ. :)   -  person Kamil Pikula    schedule 22.05.2019


คำตอบ (2)


ย้อนกลับ ไม่ ทำงาน:

library = {"1"=>{"title"=>"bbb", "money"=>10}, "2"=>{"title"=>"aaa", "money"=>12}}

sort_column = "money"

sort_direction = "asc"
library
  .sort_by {|k| k[1][sort_column]}
  .tap { |l| l.reverse! if sort_direction == "desc" }
# => [["1", {"title"=>"bbb", "money"=>10}], ["2", {"title"=>"aaa", "money"=>12}]]

sort_direction = "desc"
library
  .sort_by {|k| k[1][sort_column]}
  .tap { |l| l.reverse! if sort_direction == "desc" }
# => [["2", {"title"=>"aaa", "money"=>12}], ["1", {"title"=>"bbb", "money"=>10}]]
person fphilipe    schedule 21.05.2019
comment
ขออภัย ไม่ library ไม่ใช่ความสัมพันธ์ AR แต่เป็น ActiveSupport::HashWithIndifferentAccess - person Kamil Pikula; 21.05.2019
comment
@KamilPikula คีย์และค่าคืออะไร? คุณกำลังบอกว่ามันเป็นอาร์เรย์ของ ActiveSupport::HashWithIndifferentAccess โดยที่แต่ละองค์ประกอบเรียงลำดับเป็นแถวและคอลัมน์ที่คุณต้องการเรียงลำดับคือคีย์ในแต่ละแฮช? - person fphilipe; 21.05.2019
comment
@KamilPikula ขออภัย พลาดว่าคุณมี library ในคำถามของคุณ อัปเดตคำตอบของฉันตามนั้น - person fphilipe; 21.05.2019
comment
ให้ตายเถอะ ฉันลืมวิธี tap ใน Ruby ไปโดยสิ้นเชิง มันใช้งานได้ ขอบคุณมาก @fphilipe! - person Kamil Pikula; 22.05.2019

คุณสามารถแฮชได้ตามด้านล่าง

ถ้าเรียงลำดับตามชื่อเรื่องเท่านั้น

library.values.sort_by{|h| h["title"] }

หรือคุณต้องการเรียงลำดับตามชื่อแรกและเงินที่สองแล้วจึงใช้

library.values.sort_by{|h| [h["title"], h["money"]] }
person NensiMakawana    schedule 21.05.2019