Arrays 通过在ruby中具有多个标记的项目列表对_进行分组
我有一个对象列表,其中可能有0个或更多与它们关联的标记。在最简单的场景中,我有一个对象哈希和标记列表:Arrays 通过在ruby中具有多个标记的项目列表对_进行分组,arrays,ruby,hash,grouping,Arrays,Ruby,Hash,Grouping,我有一个对象列表,其中可能有0个或更多与它们关联的标记。在最简单的场景中,我有一个对象哈希和标记列表: collection = {'object1': ['tag1', 'tag2'], 'object2': ['tag1'], 'object3 ': ['tag2'], 'object4': []} 因此每个对象可以有许多标记 我想按每个标记将_分组并返回以下内容: {'tag1': ['object1', 'object2'], 'tag2': ['object1, 'object3']
collection = {'object1': ['tag1', 'tag2'], 'object2': ['tag1'], 'object3
': ['tag2'], 'object4': []}
因此每个对象可以有许多标记
我想按每个标记将_分组并返回以下内容:
{'tag1': ['object1', 'object2'], 'tag2': ['object1, 'object3'], nil: ['object4']}
(我不介意使用nil或空字符串或任何对象模型化“无标记”)这应该可以做到:
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
results=Hash.new
collection.map do|k,v|
v、 每个do |标签|
结果[tag.to_sym]| |=[]
结果[tag.to_sym]请尝试以下操作:
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
使用with(*)将空数组默认为对象:
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,则此单个对象将用于所有默认值
下面是两种最像Ruby的方法
#1
collection.each_with_object({}) do |(k,v),h|
v = [nil] if v.empty?
v.each { |s| (h[s] ||= []) << k }
end
#=> {"tag1"=>[:object1, :object2], "tag2"=>[:object1, :object3], nil=>[:object4]}
#2
collection.each_with_object(Hash.new { |h,k| h[k] = [] }) do |(k,v),h|
v = [nil] if v.empty?
v.each { |s| h[s] << k }
end
#=> {"tag1"=>[:object1, :object2], "tag2"=>[:object1, :object3], nil=>[:object4]}
而且h
没有键k
h[k] << v
已完成。此数据是否来自数据库?这看起来像两个表之间的左连接。否。它不是来自数据库。为什么tag.to_sym
?所以我们不能使用group\u by
方法?
(h[s] ||= []) << k
(h[s] = h[s] || []) << k
(h[s] = nil || []) << k
(h[s] = []) << k
h[s] = [k]
collection.each_with_object(Hash.new { |h,k| h[k] = [] }) do |(k,v),h|
v = [nil] if v.empty?
v.each { |s| h[s] << k }
end
#=> {"tag1"=>[:object1, :object2], "tag2"=>[:object1, :object3], nil=>[:object4]}
h = Hash.new(Hash.new { |h,k| h[k] = [] }
h[k] << v
h[k] << v