如何将metadata_hash键值全排列合并到哈希数组的每个元素中
哈希数组合并元数据笛卡尔积实现方案
需求描述
给定由哈希(键值对对象)组成的数组array_of_hashes,需要为数组中的每个元素合并另一个metadata_hash的键值组合。规则如下:
metadata_hash的所有值均为数组类型- 首先对
metadata_hash的所有值数组取笛卡尔积 - 将每一组笛卡尔积结果转为对应的键值对,再合并到
array_of_hashes的每个元素中,最终生成新的结果数组
示例说明
示例1
输入:
array_of_hashes = [{"name"=>"bob", "age"=>30}, {"name"=>"bart", "age"=>35}] metadata_hash = {"likes"=>["apples", "oranges"], "dislikes"=>["cold"]}
预期输出:
[{"name"=>"bob", "age"=>30, "likes"=>"apples", "dislikes"=>"cold"}, {"name"=>"bob", "age"=>30, "likes"=>"oranges", "dislikes"=>"cold"}, {"name"=>"bart", "age"=>35, "likes"=>"apples", "dislikes"=>"cold"}, {"name"=>"bart", "age"=>35, "likes"=>"oranges", "dislikes"=>"cold"}]
示例2
输入:
array_of_hashes = [{"name"=>"bob", "age"=>30}, {"name"=>"bart", "age"=>35}] metadata_hash = {"likes"=>["apples", "oranges"], "dislikes"=>["cold"], "courses"=>["science", "history"]}
预期输出:
[{"name"=>"bob", "age"=>30, "likes"=>"apples", "dislikes"=>"cold", "courses"=>"science"}, {"name"=>"bob", "age"=>30, "likes"=>"oranges", "dislikes"=>"cold", "courses"=>"history"}, {"name"=>"bob", "age"=>30, "likes"=>"oranges", "dislikes"=>"cold", "courses"=>"science"}, {"name"=>"bob", "age"=>30, "likes"=>"apples", "dislikes"=>"cold", "courses"=>"history"}, {"name"=>"bart", "age"=>35, "likes"=>"apples", "dislikes"=>"cold", "courses"=>"science"}, {"name"=>"bart", "age"=>35, "likes"=>"oranges", "dislikes"=>"cold", "courses"=>"history"}, {"name"=>"bart", "age"=>35, "likes"=>"oranges", "dislikes"=>"cold", "courses"=>"science"}, {"name"=>"bart", "age"=>35, "likes"=>"apples", "dislikes"=>"cold", "courses"=>"history"}]
实现方案(Ruby语言)
核心逻辑分为两步:首先生成metadata_hash所有值的笛卡尔积,转为对应的元数据哈希列表;再将原哈希数组的每个元素与所有元数据哈希合并,扁平化后得到最终结果。
实现代码:
def merge_with_metadata(array_of_hashes, metadata_hash) # 提取元数据的键列表 meta_keys = metadata_hash.keys # 对元数据的所有值数组取笛卡尔积,转为哈希列表 meta_combinations = metadata_hash.values.inject(&:product).map do |combination| meta_keys.zip(combination.flatten).to_h end # 遍历原数组每个元素,与所有元数据组合合并 array_of_hashes.flat_map do |item| meta_combinations.map { |meta| item.merge(meta) } end end
调用示例
# 测试示例1 array_of_hashes = [{"name"=>"bob", "age"=>30}, {"name"=>"bart", "age"=>35}] metadata_hash = {"likes"=>["apples", "oranges"], "dislikes"=>["cold"]} result = merge_with_metadata(array_of_hashes, metadata_hash) puts result.inspect # 输出与示例1预期一致
说明
- 代码使用
merge方法生成新哈希,不会修改原数组中的原始哈希对象 - 支持任意数量键的
metadata_hash,只要所有值都是数组即可自动计算笛卡尔积 - 最终结果长度为:原数组长度 × 元数据所有值数组长度的乘积
内容的提问来源于stack exchange,提问作者simoni
相关产品推荐
相关产品推荐

