如何用Java Streams将扁平结构对象按匹配属性分组为层级模型
扁平对象转嵌套分组对象的实现方案
核心思路
根据你指定的匹配属性层级(比如从外层到内层的分组字段),遍历扁平数组,逐步查找或创建对应的分组节点,最终构建出嵌套结构的Model_2对象。
示例实现(JavaScript)
假设你的Model_1和目标Model_2结构如下(结合配图推测):
// Model_1 扁平对象示例 const model1List = [ { category: '电子设备', subCategory: '手机', name: 'iPhone', price: 6999 }, { category: '电子设备', subCategory: '手机', name: '华为Mate', price: 5999 }, { category: '电子设备', subCategory: '平板', name: 'iPad', price: 3999 }, { category: '家居用品', subCategory: '厨具', name: '炒锅', price: 299 }, ]; // Model_2 目标嵌套结构示例 [ { category: '电子设备', subCategories: [ { subCategory: '手机', items: [ { name: 'iPhone', price: 6999 }, { name: '华为Mate', price: 5999 } ] }, { subCategory: '平板', items: [{ name: 'iPad', price: 3999 }] } ] }, { category: '家居用品', subCategories: [ { subCategory: '厨具', items: [{ name: '炒锅', price: 299 }] } ] } ]
通用转换函数:
function convertToModel2(model1Array, groupKeys) { return model1Array.reduce((result, item) => { let currentLevel = result; // 遍历分组层级,逐层构建节点 for (let i = 0; i < groupKeys.length; i++) { const key = groupKeys[i]; const keyValue = item[key]; // 检查当前层级是否已存在该分组节点 let existingNode = currentLevel.find(node => node[key] === keyValue); if (!existingNode) { // 创建新节点,区分最后一层和中间层的结构 const newNode = { [key]: keyValue }; newNode[i === groupKeys.length - 1 ? 'items' : `${groupKeys[i+1]}s`] = []; currentLevel.push(newNode); existingNode = newNode; } // 切换到下一层级 currentLevel = i === groupKeys.length - 1 ? existingNode.items : existingNode[`${groupKeys[i+1]}s`]; } // 提取非分组属性,加入到最内层items const nonGroupProps = Object.fromEntries( Object.entries(item).filter(([k]) => !groupKeys.includes(k)) ); currentLevel.push(nonGroupProps); return result; }, []); } // 调用示例:按category→subCategory分组 const model2Result = convertToModel2(model1List, ['category', 'subCategory']); console.log(model2Result);
关键说明
- 通用性:通过
groupKeys参数指定分组层级(比如['category', 'subCategory']),适配不同的分组需求 - 避免重复创建:每一层级先查找是否已有对应分组节点,不存在才新建
- 自动构建结构:根据层级位置自动生成子分组数组(如
subCategories)或最内层的items数组 - 属性分离:自动提取非分组属性,加入到最内层的列表中
Python简化实现
如果用Python处理,思路一致:
def convert_to_model2(model1_list, group_keys): result = [] for item in model1_list: current_level = result for i, key in enumerate(group_keys): key_val = item[key] # 查找当前层级的分组节点 existing_node = next((node for node in current_level if node[key] == key_val), None) if not existing_node: existing_node = {key: key_val} child_key = 'items' if i == len(group_keys)-1 else f"{group_keys[i+1]}s" existing_node[child_key] = [] current_level.append(existing_node) # 进入下一层 current_level = existing_node['items'] if i == len(group_keys)-1 else existing_node[f"{group_keys[i+1]}s"] # 添加非分组属性 non_group = {k: v for k, v in item.items() if k not in group_keys} current_level.append(non_group) return result
内容的提问来源于stack exchange,提问作者sp14
相关产品推荐
相关产品推荐

