Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有没有办法在ruby中重构以下代码_Ruby_Ruby On Rails 5 - Fatal编程技术网

有没有办法在ruby中重构以下代码

有没有办法在ruby中重构以下代码,ruby,ruby-on-rails-5,Ruby,Ruby On Rails 5,我已经写了一段代码,需要重构它 Reviewing.where(reviewing_status_condition(employee_ids)).group(:employee_id).count.map{ |employee_id, reviewings_count_per_employee| employee_id if reviewings_count_per_employee >= @cycle.min_required_anon_feedback }.compac

我已经写了一段代码,需要重构它

Reviewing.where(reviewing_status_condition(employee_ids)).group(:employee_id).count.map{ 
|employee_id, reviewings_count_per_employee|
    employee_id if reviewings_count_per_employee >= @cycle.min_required_anon_feedback
  }.compact

有人能帮忙吗?

对我来说,第一步是将
where
子句和
group
移动到指定的范围。这将减少最初的部分:

Reviewing.where(reviewing_status_condition(employee_ids)).group(:employee_id).count
更像是:

Reviewing.reviewing_count(reviewing_status_condition(employee_ids))
这并不是很短,但确实显著改善了实现与执行的分离

第二步取决于您使用的Ruby版本。在2.7版本之前,执行
map
compact
步骤的正确方法是使用
select
map
执行您已经或可以执行的操作,而Ruby 2.7引入了
filter\u map
,这是您在这里拥有的操作的一个单步组合


请参阅“”,以了解有关
filter\u map

的更多详细信息,您也可以选择让数据库处理此问题,而不是用Ruby解决此问题。然而,要做到这一点,您首先需要知道您的查询将是什么,我会选择以下内容:

选择reviewings.employee\u id
来自评论
哪里
按reviewings.employee\u id分组
拥有计数(reviewings.id)>=
这可以通过以下代码实现:

reviewings = Reviewing.arel_table

employee_ids = Reviewing
               .where(reviewing_status_condition(employee_ids))
               .group(:employee_id)
               .having(reviewings[:id].count.gteq(@cycle.min_required_anon_feedback))
               .pluck(:employee_id)
通过限制从数据库返回的数据,您可以省去Ruby端的数据操作

如果你想了解更多关于阿雷尔的信息,我建议你看看他们的网站


让我添加一个有趣的比较。假设你要点一些比萨饼

  • 你现在正在做以下事情:你打电话给你的比萨饼店,让他们每送一个比萨饼。当比萨饼到达你家时,你和你的同志们需要在吃比萨饼之前弄清楚要保留什么比萨饼,扔掉什么比萨饼

  • 我的建议是:看看菜单,弄清楚你需要什么样的比萨饼。只订购你需要的东西。当比萨饼到达你家时,所有的决定都已经做出并得到了处理(假设送货正确),你就可以享受你的比萨饼了


假设您无法按照中的建议更改数据提供。我会将您的
.map{…}.compact
更改为
.select{…}.keys
,因为它可以更好地传达您试图通过代码实现的目标。您正在根据审核计数筛选/选择某些员工ID

reviewings_count_per_employee = Reviewing.where(reviewing_status_condition(employee_ids)).group(:employee_id).count
我不确定这是否降低了时间复杂度,但它确实提高了可读性。只要你处于线性领域,我就不会太担心时间的复杂性。如果
select
is
O(N)
is
O(N)
,那么您最终得到的
O(2N)
不是真正的问题。如果你想保留你的代码
O(N)
,下面就可以了

employee_ids = []
reviewings_count_per_employee.each do |id, count| 
  employee_ids << id if count >= @cycle.min_required_anon_feedback
end
employee_id=[]
审核每名员工的人数。每名员工的id、计数
员工ID=@cycle.min\u需要反馈
结束

但是,我个人认为使用
select
的解决方案比
每个
解决方案更具可读性。虽然这可能会节省一些CPU负载,当你重新审视代码时,你的大脑必须更加努力地理解你在6-12个月内写的东西。

你希望通过这种重构实现什么?减少映射和压缩带来的时间复杂性。你是否在重构之前测试过这段代码并确保它实际工作?我可以想象,
.count.map
是有问题的,因为
.count
创建了一个计数查询并返回一个整数-但是你在它上面调用map就像调用一个集合一样。没有可能减少map的使用,然后只使用一个枚举器方法来解决这个问题吗?@mahehmesta我添加了寻址这是红宝石的。回答得好。花时间尝试用Ruby修复迭代很可能完全是浪费时间,因为问题实际上是首先将所有数据从数据库中取出。
employee_ids = []
reviewings_count_per_employee.each do |id, count| 
  employee_ids << id if count >= @cycle.min_required_anon_feedback
end