如何对Hash数组按email去重并合并roles字段?
按Email去重并合并Roles字段的Hash数组处理方案
嘿,我来帮你搞定这个需求!要实现按email去重并合并roles字段,咱们可以用Ruby的Enumerable方法优雅解决——思路很清晰:先按email分组,再合并每组的roles,同时保留其他一致的字段(这里默认同email的expression和name值是相同的,要是有不一致的情况我也会给出健壮性处理方案)。
基础实现代码
首先定义你的原始数组:
original_array = [ { "email"=>"user_name@aaa.com", "expression"=>"aaa", "name"=>"bbb", "roles"=>[:admin] }, { "email"=>"user_name@aaa.com", "expression"=>"aaa", "name"=>"bbb", "roles"=>[:manager] } ]
然后执行处理逻辑:
result = original_array.group_by { |hash| hash["email"] }.values.map do |group| # 取组内第一个元素的基础字段(假设同email的这些字段值一致) base_fields = group.first.slice("email", "expression", "name") # 合并所有roles并去重 merged_roles = group.flat_map { |item| item["roles"] }.uniq # 合并成最终的哈希 base_fields.merge("roles" => merged_roles) end
执行后result就是你想要的结果:
# => [{"email"=>"user_name@aaa.com", "expression"=>"aaa", "name"=>"bbb", "roles"=>[:admin, :manager]}]
健壮性优化(处理字段不一致情况)
如果存在同email但expression或name值不同的情况,可以添加校验逻辑,避免出现意外:
result = original_array.group_by { |hash| hash["email"] }.values.map do |group| email = group.first["email"] # 提取组内所有expression和name值并去重 unique_expressions = group.map { |item| item["expression"] }.uniq unique_names = group.map { |item| item["name"] }.uniq # 检测字段不一致并给出警告 if unique_expressions.size > 1 || unique_names.size > 1 warn "⚠️ Email #{email}存在不一致的expression或name值,请检查!" end # 构建基础字段(取第一个值,也可根据需求调整为合并/取最新等逻辑) base_fields = { "email" => email, "expression" => unique_expressions.first, "name" => unique_names.first } # 合并roles merged_roles = group.flat_map { |item| item["roles"] }.uniq base_fields.merge("roles" => merged_roles) end
这样既满足了核心需求,也能应对潜在的异常情况~
内容的提问来源于stack exchange,提问作者mbt
相关产品推荐
相关产品推荐

