I have a table for Specifications and the table contains specification_key
, specification_value
.
I’m trying to group all specifications by the specification_key
and also each group must contain only unique values.
I tried:
$specifications = Specification::whereIn('product_id', $products->pluck('id'))->get();
$SpecsGroup = $specifications->groupBy('specification_key');
dd($SpecsGroup);
This returns groups by specification_key
but these contain the same specification_value
multiple times.
IlluminateDatabaseEloquentCollection {#1572 ▼
#items: array:12 [▼
"RAM" => IlluminateDatabaseEloquentCollection {#1522 ▼
#items: array:4 [▼
0 => AppModelsSpecification {#1607 ▼
#attributes: array:6 [▼
"id" => 1
"product_id" => 1
"specification_key" => "RAM"
"specification_value" => "16 GB"
"created_at" => "2021-03-21 15:35:21"
"updated_at" => "2021-03-21 15:35:21"
]
}
1 => AppModelsSpecification {#1586 ▼
#attributes: array:6 [▼
"id" => 51
"product_id" => 2
"specification_key" => "RAM"
"specification_value" => "16 GB"
"created_at" => "2021-04-16 15:38:23"
"updated_at" => "2021-04-16 15:38:23"
]
}
2 => AppModelsSpecification {#1584 ▼
#attributes: array:6 [▼
"id" => 55
"product_id" => 3
"specification_key" => "RAM"
"specification_value" => "8 GB"
"created_at" => "2021-04-16 16:36:03"
"updated_at" => "2021-04-16 16:36:03"
]
}
3 => AppModelsSpecification {#1494 ▶}
]
}
"Brand" => IlluminateDatabaseEloquentCollection {#1503 ▶}
"Manufacturer" => IlluminateDatabaseEloquentCollection {#1562 ▶}
"Model" => IlluminateDatabaseEloquentCollection {#1563 ▶}
"Model Year" => IlluminateDatabaseEloquentCollection {#1564 ▶}
"Product Dimensions" => IlluminateDatabaseEloquentCollection {#1565 ▶}
"Model Name" => IlluminateDatabaseEloquentCollection {#1566 ▶}
"LED" => IlluminateDatabaseEloquentCollection {#1567 ▶}
"Size" => IlluminateDatabaseEloquentCollection {#1568 ▶}
"Pack" => IlluminateDatabaseEloquentCollection {#1569 ▶}
"Fan Controller" => IlluminateDatabaseEloquentCollection {#1570 ▶}
"Warranty" => IlluminateDatabaseEloquentCollection {#1571 ▶}
]
}
I want the values to be unique as in the above it currently returning the same specification_value
multiple times.
Like if it has “16 GB RAM” 2 times it should return 1 only 1 time “16 GB RAM”
How can I do that?
Thanks in advance, I’ve been trying this for the last 2 hours :(, now StackOverflow is the last hope.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
You can do simply this way:
$data = Specification::whereIn('product_id', $products->pluck('id')) ->groupBy(['specification_key', 'specification_value']) // group by query ->get() ->groupBy('specification_key'); // group by collection
array:1 [ "RAM" => array:2 [ 0 => array:6 [ "id" => 1 "product_id" => 1 "specification_key" => "RAM" "specification_value" => "16 GB" "created_at" => "2021-03-21T15:35:21.000000Z" "updated_at" => "2021-03-21T15:35:21.000000Z" ] 1 => array:6 [ "id" => 3 "product_id" => 3 "specification_key" => "RAM" "specification_value" => "8 GB" "created_at" => "2021-04-16T16:36:03.000000Z" "updated_at" => "2021-04-16T16:36:03.000000Z" ] ] ]
If you have problem with Syntax error or access violation: 1055
, you can follow this answer.
Edit your applications’s database config file
config/database.php
In mysql array, set
strict => false
to disable MySQL’s strict mode
If you want to display specification_value
only, you can use mapToGroups()
:
$data = Specification::whereIn('product_id', $products->pluck('id')) ->groupBy(['specification_key', 'specification_value']) // group by query ->get() ->mapToGroups(function ($item, $key) { return [$item['specification_key'] => $item['specification_value']]; });
array:1 [ "RAM" => array:2 [ 0 => "16 GB" 1 => "8 GB" ] ]
Method 2
After trying for hours I got this myself, I’m still not sure how I did this but it works. 😀
$specifications = Specification::whereIn('product_id', $products->pluck('id'))
->distinct('specification_value')
->groupBy('specification_value')
->distinct('specification_key')
->groupBy('specification_key')
->get()
->groupBy('specification_key');
Method 3
Use this code:
$spec_values = ['8 GB', '16 GB']; $SpecsGroup = collect(); foreach($spec_values as $spec_value) { $SpecGroup = Specification::whereIn('product_id', $products->pluck('id'))->where('specification_value', $spec_value)->first(); if ($SpecGroup !== null) { $SpecsGroup->push($SpecGroup); } } dd($SpecsGroup);
Method 4
You can use ->unique()
$specifications = Specification::whereIn('product_id', $products->pluck('id'))->unique();
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0