group_by在ruby中有很多标签的项目列表

问题描述

我有一个对象列表,其中可能有0个或多个与之关联的标签。在最简单的情况下,我有一个对象哈希和一个标记列表:

collection = {'object1': ['tag1','tag2'],'object2': ['tag1'],'object3
': ['tag2'],'object4': []}

所以每个对象可以有很多标签。

我想对每个标签进行分组并返回:

{'tag1': ['object1','object2'],'tag2': ['object1,'object3'],nil: ['object4']}

(我不介意我们使用nil还是空字符串,或者任何模型化“无标签”的对象)

解决方法

请尝试以下操作:

collection = {'object1': ['tag1','tag2'],'object2': ['tag1'],'object3': ['tag2'],'object4': []}
result = {}
collection.map do |object,tags|
  if tags.any?
    tags.each { |tag| result[tag] ||= []; result[tag] << object }
  else
    result[nil] ||= []; result[nil] << object
  end
end

结果应为:

2.6.3 :147 > result
 => {"tag1"=>[:object1,:object2],"tag2"=>[:object1,:object3],nil=>[:object4]}
,
collection = {
  'object1': ['tag1','object4': []
}
  #=> {:object1=>["tag1","tag2"],:object2=>["tag1"],:object3=>["tag2"],#    :object4=>[]}

我会说两种最类似于Ruby的方式如下。

#1

collection.each_with_object({}) do |(k,v),h|
  v = [nil] if v.empty?
  v.each { |s| (h[s] ||= []) << k }
end
  #=> {"tag1"=>[:object1,nil=>[:object4]} 

(h[s] ||= []) << k

扩展到

(h[s] = h[s] || []) << k

因此,如果h没有密钥s,则变成

(h[s] = nil || []) << k
(h[s] = []) << k
h[s] = [k]

#2

collection.each_with_object(Hash.new { |h,k| h[k] = [] }) do |(k,h|
  v = [nil] if v.empty?
  v.each { |s| h[s] << k }
end
  #=> {"tag1"=>[:object1,nil=>[:object4]}

这使用Hash::new的第三种形式来创建默认proc 。如果

h = Hash.new(Hash.new { |h,k| h[k] = [] }

h没有密钥k

h[k] << v

导致要执行的块,然后是h[k] #=> [],然后是语句

h[k] << v

完成。

,

这应该做到:

  results = Hash.new
  collection.map do |k,v|
    v.each do |tag|
      results[tag.to_sym] ||= []
      results[tag.to_sym] << k unless results[tag.to_sym].include? k
    end

    if v.empty?
      results[nil] ||= []
      results[nil] << k unless results[nil].include? k
    end
  end

  results
,

使用#enumerable#wit_object(*)和Hash#new将默认的空数组作为对象:

res = collection.each_with_object(Hash.new([])) do |(obj,tags),h|
  tags.each { |tag| h[tag] += [obj] }
  h[nil] += [obj] if tags.empty?
end

(*)如果指定了obj,则该单个对象将用于所有默认值。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...