Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.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 on rails 如何将\u按分组到给定的哈希\u映射中_Ruby On Rails_Ruby - Fatal编程技术网

Ruby on rails 如何将\u按分组到给定的哈希\u映射中

Ruby on rails 如何将\u按分组到给定的哈希\u映射中,ruby-on-rails,ruby,Ruby On Rails,Ruby,目前我有两种型号 class Author # gender # name end class Book # status -> ['published', 'in_progress'] has_one :author end 我决定使用groupby对数据集进行分组 def group_by_gender_by_status books.group_by { |book| [book.author.gender, book.status] } end 我得到的

目前我有两种型号

class Author
  # gender
  # name
end

class Book
  # status -> ['published', 'in_progress']
  has_one :author

end
我决定使用
groupby
对数据集进行分组

def group_by_gender_by_status
  books.group_by { |book| [book.author.gender, book.status] }
end
我得到的是这个

{["male", "published"] => [{BooksRecord}]
["female", "published"] => [{BooksRecord}]
["male", "in_progress"] => [{BooksRecord}]
["female", "in_progress"] => [{BooksRecord}]}
我的目标是得到这个结果

{
  female: {
    published: 10,
    in_progress: 7
  },
  male: {
    published: 6,
    in_progress: 9
  }
}

这样我就可以通过
数据[:male][:published]
访问,更容易呈现数据

我想你可以这样做:

books.group_by { |book| book.author.gender }
  .transform_values { |books| books.map(&:status).tally }
特别是,这利用了添加到ruby 2.7版中的
可枚举#tally

但是,您没有指定实际使用的是哪个ruby版本,因此如果您使用的是较旧的版本,则可以将最后一行替换为:

.transform_values { |books| books.group_by(&:status).transform_values(&:count) }

我想你可以这样做:

books.group_by { |book| book.author.gender }
  .transform_values { |books| books.map(&:status).tally }
特别是,这利用了添加到ruby 2.7版中的
可枚举#tally

但是,您没有指定实际使用的是哪个ruby版本,因此如果您使用的是较旧的版本,则可以将最后一行替换为:

.transform_values { |books| books.group_by(&:status).transform_values(&:count) }
Enumerable#group_by
只创建用于分组的键,因此不能专门使用它来生成所需的结果。此外,随着
书籍的增长,以这种方式迭代的性能将越来越差

您最好将分组和计数放在数据库上,这样返回的结果更接近您想要的最终结果,如下所示:

def group_by_gender_by_status
  books.joins(:author)
    .group(Author.arel_attribute(:gender),Book.arel_attribute(:status))
    .count
end
这将产生一个与当前的
groupby
实现类似的哈希值,但是在返回之前,将在数据库端执行计数和分组:

{["male", "published"] => 6,
["female", "published"] => 10,
["male", "in_progress"] => 9,
["female", "in_progress"] => 7}
要将其转换为所需的嵌套,我们需要对这些数据进行后期处理

def group_by_gender_by_status
  books.joins(:author)
    .group(Author.arel_attribute(:gender),Book.arel_attribute(:status))
    .count
    .each_with_object(Hash.new {|h,k| h[k] = {}}) do |((gender,status),counter),obj| 
      obj[gender.to_sym][status.to_sym] = counter
    end 
end
最终结果将与您期望的结果相同,通过将分组和计数移动到数据库级别,其降级速度应该会慢得多

注意:我不知道
书籍
来自何处,也不知道这种方法目前存在于何处。这种理解可能会进一步减少实现。

可枚举#group#U by
只创建分组键,因此不能专门使用它来生成所需的结果。此外,随着
书籍的增长,以这种方式迭代的性能将越来越差

您最好将分组和计数放在数据库上,这样返回的结果更接近您想要的最终结果,如下所示:

def group_by_gender_by_status
  books.joins(:author)
    .group(Author.arel_attribute(:gender),Book.arel_attribute(:status))
    .count
end
这将产生一个与当前的
groupby
实现类似的哈希值,但是在返回之前,将在数据库端执行计数和分组:

{["male", "published"] => 6,
["female", "published"] => 10,
["male", "in_progress"] => 9,
["female", "in_progress"] => 7}
要将其转换为所需的嵌套,我们需要对这些数据进行后期处理

def group_by_gender_by_status
  books.joins(:author)
    .group(Author.arel_attribute(:gender),Book.arel_attribute(:status))
    .count
    .each_with_object(Hash.new {|h,k| h[k] = {}}) do |((gender,status),counter),obj| 
      obj[gender.to_sym][status.to_sym] = counter
    end 
end
最终结果将与您期望的结果相同,通过将分组和计数移动到数据库级别,其降级速度应该会慢得多


注意:我不知道
书籍
来自何处,也不知道这种方法目前存在于何处。这种理解可能会进一步减少实现。

我遵循这种方法
。transform|u values{books}books.group|u by(&:status)。transform|u values(&:count)}
因为我的ruby是
2.6
,不幸的是它返回的结果是这样的
[“男性”,“发布的”=>3,“进行中的”=>10}
我必须做数据[0]==“男性”用于检查其是女性还是男性。感谢各位教授的困惑
books=[{BookRecord}]
-->array很难访问
data[0]==“male”
data[1]={:published=>1,:in_progress=>3}
@airsoftwark啊,抱歉,如果我有一点疏忽,但是你可以通过调用
.to_h
把它转换成一个好的散列——因为你有成对的值,直接转换是有意义的:我遵循这个方法
.transform_values{books}books.group_by(&:status)。transform_values(&:count)}
因为我的ruby是
2.6
,不幸的是,它像这样返回“已发布”=>3,“正在进行”=>10}]
我必须做数据[0]='male'来检查它是女性还是男性。感谢各位教授的困惑
books=[{BookRecord}]
-->数组很难访问
数据[0]==“male”
数据[1]={:published=>1,:in\u progress=>3}
@airsoftfrack啊,如果我把它弄错了,很抱歉,但是你可以通过调用
.to_h
把它转换成一个很好的散列——因为你有成对的值,直接转换是有意义的:您好,谢谢您的回答,我可以在其他地方看到使用这个方法,但是现在我把这个函数放在了
Publisher c的一个简单的delegator中lass
而且速度有点慢,因为我需要查询1000个发布者,很抱歉,我没有足够明确地说明question@airsoftFreak我不确定我是否理解您的评论,但是如果
书籍
没有加载
作者
,您现在处理它的方式将比提案慢得多,并且l导致大量的数据库点击(N+1),因为我已经做了
Book.includes(:author)
为了避免N+1,我使用simple delegator进行基本处理,但非常感谢您的帮助Hello感谢您的回答我可以在其他地方看到使用此方法,但目前我将此函数放在
Publisher类的simple delegator中
,速度有点慢,因为我需要查询1000个发布者,很抱歉没有关于这个问题要足够明确question@airsoftFreak我不确定我是否理解您的评论,但是如果
书籍
没有加载
作者
,您现在处理它的方式将比提案慢得多,并且将导致大量数据库点击(N+1),而我已经在做
书籍。包括(:author)
为了避免N+1,我使用simple delegator进行基本处理,但非常感谢您的帮助