【问题标题】:How do I get common subcategories from a category/subcategory array in PHP?如何从 PHP 中的类别/子类别数组中获取常见的子类别?
【发布时间】:2020-01-19 12:18:27
【问题描述】:

我有一个这样的数组:

Array
(
    [0] => ProductCategory Object
        (
            [name] => Non Medicated
            [id] => 6
            [subcategory] => ProductSubcategory Object
                (
                    [name] => Glass
                    [id] => 409
                )

        )

    [1] => ProductCategory Object
        (
            [name] => Non Medicated
            [id] => 6
            [subcategory] => ProductSubcategory Object
                (
                    [name] => Accesories
                    [id] => 46
                )

        )

    [2] => ProductCategory Object
        (
            [name] => Non Medicated
            [id] => 6
            [subcategory] => ProductSubcategory Object
                (
                    [name] => Lip Balm
                    [id] => 17576
                )

        )

    [3] => ProductCategory Object
        (
            [name] => Non Medicated
            [id] => 6
            [subcategory] => ProductSubcategory Object
                (
                    [name] => Lotion
                    [id] => 17577
                )

        )

    [4] => ProductCategory Object
        (
            [name] => Non Medicated
            [id] => 6
            [subcategory] => ProductSubcategory Object
                (
                    [name] => Distillate
                    [id] => 17578
                )

        )

    [5] => ProductCategory Object
        (
            [name] => Non Medicated
            [id] => 6
            [subcategory] => ProductSubcategory Object
                (
                    [name] => Cartridges
                    [id] => 17579
                )

        )

    [6] => ProductCategory Object
        (
            [name] => Non Medicated
            [id] => 6
            [subcategory] => ProductSubcategory Object
                (
                    [name] => Tincture
                    [id] => 17644
                )

        )

    [7] => ProductCategory Object
        (
            [name] => Non Medicated
            [id] => 6
            [subcategory] => ProductSubcategory Object
                (
                    [name] => Capsules
                    [id] => 17645
                )

        )

    [8] => ProductCategory Object
        (
            [name] => Infused Edible
            [id] => 4
            [subcategory] => ProductSubcategory Object
                (
                    [name] => Gummies
                    [id] => 26
                )

        )

    [9] => ProductCategory Object
        (
            [name] => Infused Edible
            [id] => 4
            [subcategory] => ProductSubcategory Object
                (
                    [name] => Chocolate Bars
                    [id] => 25
                )

        )

    [10] => ProductCategory Object
        (
            [name] => Concentrate
            [id] => 2
            [subcategory] => ProductSubcategory Object
                (
                    [name] => Live Resin
                    [id] => 15
                )

        )

    [11] => ProductCategory Object
        (
            [name] => Cartridges / Pens
            [id] => 3
            [subcategory] => ProductSubcategory Object
                (
                    [name] => Solventless
                    [id] => 18051
                )

        )

    [12] => ProductCategory Object
        (
            [name] => Concentrate
            [id] => 2
            [subcategory] => ProductSubcategory Object
                (
                    [name] => Distillate
                    [id] => 18005
                )

        )

    [13] => ProductCategory Object
        (
            [name] => Concentrate
            [id] => 2
            [subcategory] => ProductSubcategory Object
                (
                    [name] => Sauce
                    [id] => 18767
                )

        )

    [14] => ProductCategory Object
        (
            [name] => Cartridges / Pens
            [id] => 3
            [subcategory] => ProductSubcategory Object
                (
                    [name] => BHO
                    [id] => 10
                )

        )

    [15] => ProductCategory Object
        (
            [name] => Infused Edible
            [id] => 4
            [subcategory] => ProductSubcategory Object
                (
                    [name] => Baked Goods
                    [id] => 23
                )

        )

    [16] => ProductCategory Object
        (
            [name] => Infused Edible
            [id] => 4
            [subcategory] => ProductSubcategory Object
                (
                    [name] => Tincture
                    [id] => 29
                )

        )

    [17] => ProductCategory Object
        (
            [name] => Non Medicated
            [id] => 6
            [subcategory] => ProductSubcategory Object
                (
                    [name] => Vaporizers
                    [id] => 42
                )

        )

    [18] => ProductCategory Object
        (
            [name] => Infused Edible
            [id] => 4
            [subcategory] => ProductSubcategory Object
                (
                    [name] => Cooking Oil
                    [id] => 18864
                )

        )

    [19] => ProductCategory Object
        (
            [name] => Concentrate
            [id] => 2
            [subcategory] => ProductSubcategory Object
                (
                    [name] => RSO
                    [id] => 18865
                )

        )

    [20] => ProductCategory Object
        (
            [name] => Concentrate
            [id] => 2
            [subcategory] => ProductSubcategory Object
                (
                    [name] => Sugar (Each)
                    [id] => 18876
                )

        )

    [21] => ProductCategory Object
        (
            [name] => Non Medicated
            [id] => 6
            [subcategory] => ProductSubcategory Object
                (
                    [name] => Shirts
                    [id] => 44
                )

        )

    [22] => ProductCategory Object
        (
            [name] => Infused Edible
            [id] => 4
            [subcategory] => ProductSubcategory Object
                (
                    [name] => Sweets
                    [id] => 27
                )

        )

    [23] => ProductCategory Object
        (
            [name] => Non Medicated
            [id] => 6
            [subcategory] => ProductSubcategory Object
                (
                    [name] => CBD Bath Bomb
                    [id] => 19461
                )

        )

    [24] => ProductCategory Object
        (
            [name] => Non Medicated
            [id] => 6
            [subcategory] => ProductSubcategory Object
                (
                    [name] => Edibles
                    [id] => 17580
                )

        )

    [25] => ProductCategory Object
        (
            [name] => Infused Edible
            [id] => 4
            [subcategory] => ProductSubcategory Object
                (
                    [name] => Capsules/Pills
                    [id] => 22
                )

        )

)

ProductCategory 对象的定义如下:

class ProductCategory{
    public $name;
    public $id;
    public $subcategory;

    public function __construct($categoryName, $categoryId, $subcategory){
        $this->name = $categoryName;
        $this->id = $categoryId;
        $this->subcategory = $subcategory;
    }
}

ProductSubcategory 的定义如下:

class ProductSubcategory{

    public $name;
    public $id;

    public function __construct($subcategoryName, $subcategoryId){
        $this->name = $subcategoryName;
        $this->id = $subcategoryId;

    }

我正在尝试获取属于同一类别的所有子类别。例如,在上面数组的位置 0 和 1,Glass 和 Accessories 子类别都属于 Non Medicated 类别。

最终我试图获得这样的显示(我不想显示类别和子类别编号,但我需要它们以供以后使用):

  • 非药物 (id = 6)

    • 玻璃(类别 ID = 6,子类别 ID = 409)
    • 附件(类别 ID = 6,子类别 ID = 46)
    • 润唇膏
    • 乳液
    • 馏出物
    • 墨盒
    • 酊剂
    • 胶囊
    • 汽化器
    • 衬衫
    • CBD 沐浴炸弹
    • 食物
  • 浸泡食用 (id = 4)

    • 软糖(类别 ID = 4,子类别 ID = 26)
    • 巧克力棒
    • 烘焙食品
    • 酊剂
    • 食用油
    • 糖果
    • 胶囊/丸剂
  • 专注

    • 活性树脂
    • 馏出物
    • 酱汁
    • 糖(每份)
  • 墨盒/笔

    • 无溶剂
    • BHO

此最终输出将是用户可以单击的单选按钮 - 如果他们单击父类别,产品将按该父类别过滤。如果他们单击子类别,产品将按该父类别以及子类别进行过滤。

我唯一尝试过的是从数组中获得一个不同的父类别列表,并尝试遍历它们,然后为每个父类别循环遍历上面的数组并检查该类别是否与父类别匹配,然后追加子类别对象。

由于某种原因,我无法让它工作。我不知道我是否只需要放弃使用对象本身并返回一组名称和 ID 或什么。任何指导将不胜感激。

这与我昨天问的question 有关,其中有人帮助我重新设计了 ProductCategory 对象。我比昨天更接近了,但仍然没有。

编辑

以下是类别和子类别的分组方式:

public function get_categories_from_all_products() {

    $categories  = array();
    $allProducts = $this->get_all_products();

    foreach ( $allProducts as $item ) {
        if ( ! in_array( $item->category, $categories ) ) {
            array_push( $categories, $item->category );
        }
    }

    return $categories;
}

get_all_products 返回一个 Product 对象数组,其定义如下:

class Product{

    public $description;
    public $pricing;
    public $name;
    public $imageUrl;
    public $id;
    public $category;

    public function __construct($id, $description, $pricing, $name, $imageUrl, ProductCategory $category){
        $this->description = $description;
        $this->pricing = $pricing;
        $this->name = $name;
        $this->imageUrl = $imageUrl;
        $this->id = $id;
        $this->category = $category;
    }

}

示例产品声明(这里的 $item 来自 API 调用返回的产品数组):

$p = new Product(
    $item['id'],
    $item['description'] ? $item['description'] : 'No product description.',
    $price,
    $item["name"],
    array_key_exists('primary_image_urls', $item) ? $item['primary_image_urls'] : 'img/no_image_available.png',
    new ProductCategory( $item['category_name'], $item['category_id'], new ProductSubcategory( $item['subcategory_name'], $item['subcategory_id']) )
);

最终编辑:

对已接受的答案稍作调整:

foreach($categories as $category){

    $cat = $category->name;
    $id = $category->id;
    $toRet[$id][$cat][] = $category->subcategory;


 }

return $toRet;

测试显示(注意:我添加了逻辑,以便如果父类别只有一个子类别,它将只显示父类别):

$categories = $MJPlugin->get_categories_from_all_products(); //Populates array from above

echo '<ul>';


foreach( $categories as $categoryId => $category ) {

    $cat = key( $categories[$categoryId] );

    echo '<li>' . $cat . '</li>';

    echo '<ul>';

    foreach( $categories[$categoryId] as $subcategories ) {

        if( count( $subcategories ) > 1 ) {
            foreach( $subcategories as $subcategory ) {

                echo '<li>' . $subcategory->name . '</li>';
            }
        }
    }

    echo '</ul>';

}

echo '<ul>';

【问题讨论】:

  • 您能显示将类别/子类别分组的代码的 sn-p 吗?
  • 另外,您对ProductCategory::$subcategory 成员的命名让我怀疑您是否在这里记住了正确的关系。我觉得应该是$subcategories(一对多而不是一对一)
  • 我更新了一些附加信息。是的,我开始为每个类别设置一系列子类别。不幸的是,我受到 API 调用的限制。我只是得到一个包含名称、描述、价格、项目类别和项目子类别的项目列表。从这个项目/产品列表中,我试图建立独特的类别/子类别关系。我受到 API 的限制。
  • 一次检查我的答案。可能在一定程度上有所帮助

标签: php arrays


【解决方案1】:

下面的代码可以帮助你处理原始数组(你可以通过 toArray() 来实现),

$parentCategories = [6, 4, 3, 2];
$result           = [];
foreach ($parentCategories as $key => $pv) {
    foreach ($childCategories as $cv) {
        if ($pv == $cv['id']) {
            if (empty($result[$cv['id']]['name'])) {
                $result[$cv['id']]['data']['id'] = $pv;
                $result[$cv['id']]['data']['name']       = $cv['name'];
            }
            $result[$cv['id']]['children'][] = $cv['subcategory'];
        }
    }
}

Demo

输出:-

                      (
                            [name] => Cartridges
                            [id] => 17579
                        )

                    [6] => Array
                        (
                            [name] => Tincture
                            [id] => 17644
                        )

                    [7] => Array
                        (
                            [name] => Capsules
                            [id] => 17645
                        )

                    [8] => Array
                        (
                            [name] => Vaporizers
                            [id] => 42
                        )

                    [9] => Array
                        (
                            [name] => Shirts
                            [id] => 44
                        )

                    [10] => Array
                        (
                            [name] => CBD Bath Bomb
                            [id] => 19461
                        )

                    [11] => Array
                        (
                            [name] => Edibles
                            [id] => 17580
                        )

                )

        )

    [4] => Array
        (
            [data] => Array
                (
                    [id] => 4
                    [name] => Infused Edible
                )

            [children] => Array
                (
                    [0] => Array
                        (
                            [name] => Gummies
                            [id] => 26
                        )

                    [1] => Array
                        (
                            [name] => Chocolate Bars
                            [id] => 25
                        )

                    [2] => Array
                        (
                            [name] => Baked Goods
                            [id] => 23
                        )

                    [3] => Array
                        (
                            [name] => Tincture
                            [id] => 29
                        )

                    [4] => Array
                        (
                            [name] => Cooking Oil
                            [id] => 18864
                        )

                    [5] => Array
                        (
                            [name] => Sweets
                            [id] => 27
                        )

                    [6] => Array
                        (
                            [name] => Capsules/Pills
                            [id] => 22
                        )

                )

        )

    [3] => Array
        (
            [data] => Array
                (
                    [id] => 3
                    [name] => Cartridges / Pens
                )

            [children] => Array
                (
                    [0] => Array
                        (
                            [name] => Solventless
                            [id] => 18051
                        )

                    [1] => Array
                        (
                            [name] => BHO
                            [id] => 10
                        )

                )

        )

    [2] => Array
        (
            [data] => Array
                (
                    [id] => 2
                    [name] => Concentrate
                )

            [children] => Array
                (
                    [0] => Array
                        (
                            [name] => Live Resin
                            [id] => 15
                        )

                    [1] => Array
                        (
                            [name] => Distillate
                            [id] => 18005
                        )

                    [2] => Array
                        (
                            [name] => Sauce
                            [id] => 18767
                        )

                    [3] => Array
                        (
                            [name] => RSO
                            [id] => 18865
                        )

                    [4] => Array
                        (
                            [name] => Sugar (Each)
                            [id] => 18876
                        )

                )

        )

)

我从逻辑上获取脚本的输出,

foreach ($result as $key => $value) {
    echo "<ul>";
    echo "<li>" . $value['data']['name'] . '(' . 'id=' . $value['data']['id'] . ')';
    echo "<ul>";
    foreach ($value['children'] as $k => $value1) {
        echo "<li>";
        if ($k == 0) {
            echo $value1['name'] . "(" . 'categoryid = ' . $value['data']['id'] . ', subcategoryid = ' . $value1['id'] . ")";
        } else {
            echo $value1['name'];
        }
        echo "</li>";
    }
    echo "</ul></li></ul>";
}

输出为

<ul>
  <li>Non Medicated(id=6)
    <ul>
      <li>Glass(categoryid = 6, subcategoryid = 409)</li>
      <li>Accesories</li>
      <li>Lip Balm</li>
      <li>Lotion</li>
      <li>Distillate</li>
      <li>Cartridges</li>
      <li>Tincture</li>
      <li>Capsules</li>
      <li>Vaporizers</li>
      <li>Shirts</li>
      <li>CBD Bath Bomb</li>
      <li>Edibles</li>
    </ul>
  </li>
</ul>
<ul>
  <li>Infused Edible(id=4)
    <ul>
      <li>Gummies(categoryid = 4, subcategoryid = 26)</li>
      <li>Chocolate Bars</li>
      <li>Baked Goods</li>
      <li>Tincture</li>
      <li>Cooking Oil</li>
      <li>Sweets</li>
      <li>Capsules/Pills</li>
    </ul>
  </li>
</ul>
<ul>
  <li>Cartridges / Pens(id=3)
    <ul>
      <li>Solventless(categoryid = 3, subcategoryid = 18051)</li>
      <li>BHO</li>
    </ul>
  </li>
</ul>
<ul>
  <li>Concentrate(id=2)
    <ul>
      <li>Live Resin(categoryid = 2, subcategoryid = 15)</li>
      <li>Distillate</li>
      <li>Sauce</li>
      <li>RSO</li>
      <li>Sugar (Each)</li>
    </ul>
  </li>
</ul>

【讨论】:

  • 我正在查看代码,但确实收到了错误Uncaught Error: Cannot use object of type ProductCategory as array。 Ed:哦,我想我需要做 toArray(),但看起来我需要自己定义 toArray() 函数?
  • ToArray 由 laravel 自己提供。您可以查看文档或使用收集
【解决方案2】:

我像你一样创建了一个假对象 ($categories)。

希望这会有所帮助:

<?php

 $categories = array();

 $obj0 = new stdClass;
 $obj0->id = 123;
 $obj0->name = "Non Medicated";
 $obja = new stdClass;
 $obja->name = "Glass";
 $obja->id = 409;
 $obj0->subcategory =$obja;
 $categories[0] = $obj0;

 $obj1 = new stdClass;
 $obj1->id = 124;
 $obj1->name = "Non Medicated";
 $obj1a = new stdClass;
 $obj1a->name = "Capsules";
 $obj1a->id = 410;
 $obj1->subcategory =$obj1a;
 $categories[1] = $obj1;

 $obj2 = new stdClass;
 $obj2->id = 125;
 $obj2->name = "Non Medicated";
 $obj2a = new stdClass;
 $obj2a->name = "Capsules";
 $obj2a->id = 411;
 $obj2->subcategory =$obj2a;
 $categories[2] = $obj2;

 $toRet =array();

 foreach($categories as $category){
    $cat = $category->name;
    $toRet[$cat][] = $category->subcategory;
 }

 var_dump($toRet);

这是var_dump函数的输出:

array(1) { ["Non Medicated"]=> array(3) { [0]=> object(stdClass)#2 (2) { ["name"]=> string(5) "Glass" ["id"]=> int(409) } [1]=> object(stdClass)#4 (2) { ["name"]=> string(8) "Capsules" ["id"]=> int(410) } [2]=> object(stdClass)#6 (2) { ["name"]=> string(8) "Capsules" ["id"]=> int(411) } } }

【讨论】:

  • 这主要是有效的。我需要解决的一件事是我丢失了父类别的 id(例如,非药物是 id = 6)。我希望用户能够选择父类别(我需要 id)或子类别。
  • 是的,但是您有类别的 ID。这对你来说已经足够了。
【解决方案3】:

不确定我是否理解你想要的,但如果你只需要显示类别和子类别,你可以这样做吗?

foreach($categories as $key => $category){

    echo $category->name;
    echo $category->id;

    foreach($category->subcategory as $key2 => $subCategory){

        echo $subCategory->name;
        echo $subCategory->id;
        echo $category->id;
    }
}                

【讨论】:

  • 正在尝试适应,但出现此错误:Trying to get property 'name' of non-object
  • 最终输出将是单选按钮,用户可以在其中选择父类别,这将按父类别过滤产品。或者用户可以按子类别进行过滤,产品将按类别和子类别进行过滤。
  • 不幸的是,同样的事情。当我在内部 foreach 循环中 var_dump 时,它没有显示对象,但是如果我在第一个 foreach 内部但在内部 foreach 之前 var_dump $category-&gt;subcategory ,它会很好地显示 ProductSubcategory 对象。奇数。
猜你喜欢
  • 2023-03-17
  • 1970-01-01
  • 2015-08-14
  • 2015-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-30
  • 1970-01-01
相关资源
最近更新 更多