Ruby 通过键对多维数组进行排序

标签 ruby sinatra

我想对数组进行排序以按升序或降序排序。 我的数组包含散列键,我想要排序的值是 float 、整数和字符串(名称)。名称可以是字母或字母数字。我想创建一个可以处理所有排序的方法。它将获取数组、列名和排序顺序,并返回排序后的数组的其余部分。 以下是 JSON 输出。我的数组包含哈希键。

[
  {
    "sid": "101",
    "snumber": "798798",
    "name": "Anita 1",
    "time": 1800,
    "count": 32,
    "hour": "",
    "avg": 1
  },
  {
    "sid": "160",
    "snumber": "6546546",
    "name": "Anita 22",
    "time": 1300,
    "count": 30,
    "hour": "1",
    "avg": 1
  },
  {
    "sid": "120",
    "snumber": "6546546",
    "name": "Anita",
    "time": 2300,
    "count": 10,
    "hour": "2",
    "avg": 2
  }
]

我尝试了很多东西,但都做不好。这是我的方法:

def self.sort_by_alphabets(arr, sortColumnName, sortOrder) # sortOrder a: ASC,d: DESC
    column = sortColumnName.to_sym
    return arr.sort_by { |h| 
        if sortColumnName == 'sid' || sortColumnName = 'snumber' || sortColumnName =='hour'
            a = h[column].to_i
        else
            if h[column].is_a? String
                a = h[column].to_s
                type ='s'
            elsif h[column].is_a? Float
                a = h[column].to_f
                type ='f'
            else
                a = h[column].to_i
                type ='i'
            end

       if sortOrder == 'a'
        a.downcase
       else
        a.upcase
       end

    }
  end

谁能帮帮我?

预期的输出是一个排序数组。假设我想使用 sid 按升序对数组进行排序,那么结果数组将按上述顺序按 sid 排序,对于其他键也是如此。但是,数组一次只能按任何一个键排序。

最佳答案

代码

def sort_by_value(arr, key, ascending = true)
  arr.sort_by do |h|
    v = h[key]
    raise TypeError, "#{v}.class => #{v.class} invalid" unless
      (v.kind_of?(Numeric) && !v.is_a?(Complex)) || v.is_a?(String)
    Float(v) rescue v.downcase
  end.tap { |a| a.reverse! if ascending == false }
end

参见 Enumerable#sort_by , Object#kind_of?Kernel#Float .

我假设当值是表示数值(复数除外)的字符串时,将对关联的数字进行排序。 Float(v) 尝试将字符串 v 转换为 float 。如果成功则返回 float;否则它会引发一个被挽救的异常(在线),导致 v.downcase 被返回。

示例

arr = [
  { "name"=>"Anita 1",  "time"=>18, "wt"=>2.31,  "inbr"=>  "79", "fnbr"=>"-2.31"    },
  { "name"=>"Anita 22", "time"=>13, "wt"=>-12.4, "inbr"=> "654", "fnbr"=>"12.4"     },
  { "name"=>"bubba",    "time"=>23, "wt"=>12.84, "inbr"=>"-654", "fnbr"=>"-1284e-2" }
]

sort_by_value(arr, "name")
  #=> [{"name"=>"Anita 1", "time"=>18, "wt"=>2.31, "inbr"=>"79","fnbr"=>"-2.31"}
  #    {"name"=>"Anita 22", "time"=>13, "wt"=>-12.4, "inbr"=>"654","fnbr"=>"12.4"},
  #    {"name"=>"bubba", "time"=>23, "wt"=>12.84, "inbr"=>"-654","fnbr"=>"-1284e-2"}]
sort_by_value(arr, "name", false)
  #=> [{"name"=>"bubba", "time"=>23, "wt"=>12.84, "inbr"=>"-654",  "fnbr"=>"-1284e-2"},
  #    {"name"=>"Anita 22", "time"=>13, "wt"=>-12.4, "inbr"=>"654",  "fnbr"=>"12.4"},
  #    {"name"=>"Anita 1", "time"=>18, "wt"=>2.31, "inbr"=>"79",  "fnbr"=>"-2.31"}]

sort_by_value(arr, "time")
  #=> [{"name"=>"Anita 22", "time"=>13, "wt"=>-12.4, "inbr"=>"654", "fnbr"=>"12.4"},
  #    {"name"=>"Anita 1", "time"=>18, "wt"=>2.31, "inbr"=>"79", "fnbr"=>"-2.31"},
  #    {"name"=>"bubba", "time"=>23, "wt"=>12.84, "inbr"=>"-654", "fnbr"=>"-1284e-2"}]
sort_by_value(arr, "time", false)
  #=> [{"name"=>"bubba", "time"=>23, "wt"=>12.84, "inbr"=>"-654", "fnbr"=>"-1284e-2"},
  #    {"name"=>"Anita 1", "time"=>18, "wt"=>2.31, "inbr"=>"79", "fnbr"=>"-2.31"},
  #    {"name"=>"Anita 22", "time"=>13, "wt"=>-12.4, "inbr"=>"654", "fnbr"=>"12.4"}]

sort_by_value(arr, "wt")
  #=> [{"name"=>"Anita 22", "time"=>13, "wt"=>-12.4, "inbr"=>"654", "fnbr"=>"12.4"},
  #    {"name"=>"Anita 1", "time"=>18, "wt"=>2.31, "inbr"=>"79", "fnbr"=>"-2.31"},
  #    {"name"=>"bubba", "time"=>23, "wt"=>12.84, "inbr"=>"-654", "fnbr"=>"-1284e-2"}]
sort_by_value(arr, "wt", false)
  #=> [{"name"=>"bubba", "time"=>23, "wt"=>12.84, "inbr"=>"-654", "fnbr"=>"-1284e-2"},
  #    {"name"=>"Anita 1", "time"=>18, "wt"=>2.31, "inbr"=>"79", "fnbr"=>"-2.31"},
  #    {"name"=>"Anita 22", "time"=>13, "wt"=>-12.4, "inbr"=>"654", "fnbr"=>"12.4"}]

sort_by_value(arr, "inbr")
  #=> [{"name"=>"bubba", "time"=>23, "wt"=>12.84, "inbr"=>"-654", "fnbr"=>"-1284e-2"},
  #    {"name"=>"Anita 1", "time"=>18, "wt"=>2.31, "inbr"=>"79", "fnbr"=>"-2.31"},
  #    {"name"=>"Anita 22", "time"=>13, "wt"=>-12.4, "inbr"=>"654", "fnbr"=>"12.4"}]
sort_by_value(arr, "inbr", false)
  #=> [{"name"=>"Anita 22", "time"=>13, "wt"=>-12.4, "inbr"=>"654", "fnbr"=>"12.4"},
  # {"name"=>"Anita 1", "time"=>18, "wt"=>2.31, "inbr"=>"79", "fnbr"=>"-2.31"},
  # {"name"=>"bubba", "time"=>23, "wt"=>12.84, "inbr"=>"-654", "fnbr"=>"-1284e-2"}]

sort_by_value(arr, "fnbr")
  #=> [{"name"=>"bubba", "time"=>23, "wt"=>12.84, "inbr"=>"-654", "fnbr"=>"-1284e-2"},
  #    {"name"=>"Anita 1", "time"=>18, "wt"=>2.31, "inbr"=>"79", "fnbr"=>"-2.31"},
  #    {"name"=>"Anita 22", "time"=>13, "wt"=>-12.4, "inbr"=>"654", "fnbr"=>"12.4"}]
sort_by_value(arr, "fnbr", false)
  #=> [{"name"=>"Anita 22", "time"=>13, "wt"=>-12.4, "inbr"=>"654", "fnbr"=>"12.4"},
  #    {"name"=>"Anita 1", "time"=>18, "wt"=>2.31, "inbr"=>"79", "fnbr"=>"-2.31"},
  #    {"name"=>"bubba", "time"=>23, "wt"=>12.84, "inbr"=>"-654", "fnbr"=>"-1284e-2"}]

关于Ruby 通过键对多维数组进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51209886/

相关文章:

ruby - Heroku Postgres 连接上限为 5/20

ruby - Sinatra-为什么404错误阻止永远不会触发?

Ruby 的 'or' 与 '||'

ruby-on-rails - 通过关联从具有多个关联中获取第一个关联

ruby-on-rails - Gem unf_ext 未能构建 gem native 扩展

ruby - Sidekiq 作业 - 在条件下返回失败或成功

ruby - 在单个 csv.new() 行中创建一个带有标题的新 Ruby CSV 对象

ruby-on-rails - 为我的 Rails 应用程序创建自定义配置选项的最佳方式?

ruby - Sinatra 服务器响应超时

ruby - 那里有任何非 Rails ruby​​ 论坛应用程序吗?