You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过循环将子分类产品数量累加到各级父分类?

如何将子分类产品数量累加到父分类(含多级父分类)

需要把所有子分类(包括多级子分类)的产品数量,逐层累加到对应的父分类中,最终每个父分类的count值是自身产品数加上所有子分类的产品数总和。

核心思路

从最底层的分类(叶子节点)开始,逐层向上遍历父分类,将当前分类的产品数累加到每个父分类的count中,避免重复计算,确保所有子分类的数量都被正确汇总到上级分类。


方法一:筛选叶子节点后向上累加

先找出所有没有子分类的叶子节点,再逐个将它们的产品数向上传递到所有父分类。

代码示例

// 假设你的分类数组为 $categories(键为分类ID,值包含id、parent_id、count字段)
$calculatedCategories = $categories; // 复制原数组,避免修改原始数据

// 1. 收集所有父分类ID的集合,用于判断是否为叶子节点
$parentIds = array_column($calculatedCategories, 'parent_id');

// 2. 筛选叶子节点:ID不在父ID集合中的分类(无任何子分类)
$leafCategories = array_filter($calculatedCategories, function($category) use ($parentIds) {
    return !in_array($category['id'], $parentIds);
});

// 3. 遍历叶子节点,向上累加产品数到所有父分类
foreach ($leafCategories as $leaf) {
    $currentParentId = $leaf['parent_id'];
    $countToAdd = $leaf['count'];
    
    // 循环向上查找父分类,直到顶级分类(parent_id为null)
    while ($currentParentId !== null && isset($calculatedCategories[$currentParentId])) {
        $calculatedCategories[$currentParentId]['count'] += $countToAdd;
        // 获取上一级父分类ID
        $currentParentId = $calculatedCategories[$currentParentId]['parent_id'];
    }
}

// 此时 $calculatedCategories 即为汇总后的分类数组

说明

  • 复制原数组是为了保留原始数据,不需要的话可直接操作原数组。
  • array_column提取所有分类的parent_id,以此判断分类是否为叶子节点(无其他分类以它为父类)。
  • 通过while循环向上遍历父分类链,确保每个叶子节点的产品数被所有上级父分类汇总。

方法二:按分类深度排序后累加

若担心叶子节点筛选出错,可先给所有分类按层级深度从深到浅排序,再遍历每个分类向上累加,确保子分类先于父类被处理。

代码示例

$calculatedCategories = $categories;
$depthCache = []; // 缓存分类深度,提升计算效率

// 递归计算分类的层级深度
function getCategoryDepth($categoryId, $categories, &$depthCache) {
    if (isset($depthCache[$categoryId])) {
        return $depthCache[$categoryId];
    }
    $category = $categories[$categoryId];
    if ($category['parent_id'] === null) {
        return $depthCache[$categoryId] = 0;
    }
    // 当前分类深度 = 父分类深度 + 1
    return $depthCache[$categoryId] = getCategoryDepth($category['parent_id'], $categories, $depthCache) + 1;
}

// 按分类深度降序排序(最深的分类排在最前面)
usort($calculatedCategories, function($a, $b) use ($calculatedCategories, &$depthCache) {
    $depthA = getCategoryDepth($a['id'], $calculatedCategories, $depthCache);
    $depthB = getCategoryDepth($b['id'], $calculatedCategories, $depthCache);
    return $depthB - $depthA;
});

// 遍历排序后的分类,向上累加产品数
foreach ($calculatedCategories as &$category) {
    $currentParentId = $category['parent_id'];
    while ($currentParentId !== null && isset($calculatedCategories[$currentParentId])) {
        $calculatedCategories[$currentParentId]['count'] += $category['count'];
        $currentParentId = $calculatedCategories[$currentParentId]['parent_id'];
    }
}
unset($category); // 释放引用,避免后续数组操作异常

// 汇总后的分类数组已保存在 $calculatedCategories 中

说明

  • getCategoryDepth通过递归计算分类深度,并用缓存避免重复计算,适合大规模分类数组。
  • usort将分类按深度从深到浅排序,确保子分类的数量先被累加到父分类中,避免遗漏。

注意事项

  • 确认分类数组中parent_id对应的是分类的数组键(如示例中的1、2、21),而非数据库的id字段。
  • 若产品属于多个分类,代码会正常累加每个分类的产品数到各自的父分类链中。
  • 3000个分类的规模下,两种方法均可高效处理,方法一性能略优,方法二更适配复杂分类结构。

内容的提问来源于stack exchange,提问作者Rediska

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 12:59:54