如何重新格式化 laravel 关系集合

How to re-format laravel relationship collections

我有以下模型及其关系:

产品 -(名称、价格、数量)

产品属性(数量、价格-有组合时,这里的数量和价格为一个)

属性-(尺码、颜色)

属性值 -(小、中、大、红、蓝、绿等)

// One to Many Relationship
$product->productAttributes (returns a collection)

// Many to Many Relationship
$productAttribute->attributeValues (returns a collection)

// One to Many Relationship
$attribute->attributeValues

我需要将其格式化为:

array:2 [
  "color" => array:2 [
    0 => "red"
    1 => "blue"
  ]
  "size" => array:3 [
    0 => "small"
    1 => "medium"
    2 => "large"
  ]
]

这是我迭代集合时得到的结果:

    $attributes = $productAttributes->map(function (ProductAttribute $pa){
        return $pa->attributesValues->map(function (AttributeValue $av) {
            return [$av->attribute->name => $av->value];
        });
    })->all();

很明显returns:

array:6 [▼
  0 => Collection {#508 ▼
    #items: array:2 [▼
      0 => array:1 [▼
        "Color" => "red"
      ]
      1 => array:1 [▼
        "Size" => "small"
      ]
    ]
  }
  1 => Collection {#525 ▼
    #items: array:2 [▼
      0 => array:1 [▼
        "Color" => "red"
      ]
      1 => array:1 [▼
        "Size" => "medium"
      ]
    ]
  }
  2 => Collection {#535 ▼
    #items: array:2 [▼
      0 => array:1 [▼
        "Color" => "red"
      ]
      1 => array:1 [▼
        "Size" => "large"
      ]
    ]
  }
  3 => Collection {#545 ▼
    #items: array:2 [▼
      0 => array:1 [▼
        "Color" => "red"
      ]
      1 => array:1 [▼
        "Size" => "small"
      ]
    ]
  }
]

同样,我的目的是将其格式化为:

array:2 [
  "color" => array:2 [
    0 => "red"
    1 => "blue"
  ]
  "size" => array:3 [
    0 => "small"
    1 => "medium"
    2 => "large"
  ]
]

TIA!

编辑:

$product->productAttributes

    Collection {#513 ▼
      #items: array:6 [▼
        0 => ProductAttribute {#514 ▼
          #fillable: array:2 [▶]
          #connection: "mysql"
          #table: null
          #primaryKey: "id"
          #keyType: "int"
          +incrementing: true
          #with: []
          #withCount: []
          #perPage: 15
          +exists: true
          +wasRecentlyCreated: false
          #attributes: array:6 [▶]
          #original: array:6 [▼
            "id" => 7
            "quantity" => 3
            "price" => "100.00"
            "product_id" => 25
            "created_at" => "2018-03-11 16:56:36"
            "updated_at" => "2018-03-11 16:56:36"
          ]
          #changes: []
          #casts: []
          #dates: []
          #dateFormat: null
          #appends: []
          #dispatchesEvents: []
          #observables: []
          #relations: []
          #touches: []
          +timestamps: true
          #hidden: []
          #visible: []
          #guarded: array:1 [▶]
        }
        1 => ProductAttribute {#515 ▶}
        2 => ProductAttribute {#516 ▶}
        3 => ProductAttribute {#517 ▶}
        4 => ProductAttribute {#518 ▶}
        5 => ProductAttribute {#519 ▶}
      ]
    }

    $productAttribute->attributeValues

array:6 [▼
  0 => Collection {#507 ▼
    #items: array:2 [▼
      0 => AttributeValue {#521 ▼
        #fillable: array:1 [▶]
        #connection: "mysql"
        #table: null
        #primaryKey: "id"
        #keyType: "int"
        +incrementing: true
        #with: []
        #withCount: []
        #perPage: 15
        +exists: true
        +wasRecentlyCreated: false
        #attributes: array:5 [▶]
        #original: array:7 [▼
          "id" => 1
          "value" => "red"
          "attribute_id" => 1
          "created_at" => "2018-03-11 16:49:15"
          "updated_at" => "2018-03-11 16:49:15"
          "pivot_product_attribute_id" => 7
          "pivot_attribute_value_id" => 1
        ]
        #changes: []
        #casts: []
        #dates: []
        #dateFormat: null
        #appends: []
        #dispatchesEvents: []
        #observables: []
        #relations: array:1 [▶]
        #touches: []
        +timestamps: true
        #hidden: []
        #visible: []
        #guarded: array:1 [▶]
      }
      1 => AttributeValue {#506 ▼
        #fillable: array:1 [▶]
        #connection: "mysql"
        #table: null
        #primaryKey: "id"
        #keyType: "int"
        +incrementing: true
        #with: []
        #withCount: []
        #perPage: 15
        +exists: true
        +wasRecentlyCreated: false
        #attributes: array:5 [▶]
        #original: array:7 [▶]
        #changes: []
        #casts: []
        #dates: []
        #dateFormat: null
        #appends: []
        #dispatchesEvents: []
        #observables: []
        #relations: array:1 [▶]
        #touches: []
        +timestamps: true
        #hidden: []
        #visible: []
        #guarded: array:1 [▶]
      }
    ]
  }
  1 => Collection {#523 ▶}
  2 => Collection {#530 ▶}
  3 => Collection {#537 ▶}
  4 => Collection {#544 ▶}
  5 => Collection {#547 ▶}
]

我想,你要找的是类似下面的东西;

$attributes = $productAttributes->pluck('attributesValue')
    ->flatten()
    ->unique()
    ->groupBy(function (AttributeValue $av) {
        return $av->attribute->name;
    })
    ->each(function (Collection $avs) {
        $avs->map(function (AttributeValue $av) {
            return $av->value;
        });
    });

以上代码的作用如下;

  • 为所有结果拉关系 attributesValue
  • 将其展平,这样我们就有了一个包含所有 attributesValue
  • 的集合
  • 确保我们没有任何重复项
  • 我们将所有内容分组,这样我们就有了 colour => (collection of colour attributesValue)
  • 现在我们循环遍历我们的多级集合,并映射 AttributeValue 的实例,以便每个都用它们的值替换

我自己没有运行这个代码,但我相信它会起作用。