PHP: manipulate array making value as key recursively - php

I got this array:
array:2 [▼
0 => array:1 [▼
0 => array:7 [▼
"id" => "1"
"producer" => "Samsung"
"model" => "LE22B541C4W"
"category" => "1"
"production_date" => "2009-05-08"
"status" => "Discontinued"
"type" => "LCD"
]
]
1 => array:1 [▼
0 => array:7 [▼
"id" => "2"
"producer" => "Samsung"
"model" => "P24FHD"
"category" => "1"
"production_date" => "0000-00-00"
"status" => "Discontinued"
"type" => "LCD"
]
]
[...]
]
I would like to take the "ID" value of each array and make as primary key and remove the useless keys like this
array:2 [
1 => array:7 [
"id" => "1"
"producer" => "Samsung"
"model" => "LE22B541C4W"
"category" => "1"
"production_date" => "2009-05-08"
"status" => "Discontinued"
"type" => "LCD"
]
2 => array:7 [
[...]
By now I'm just populate the array using this simple query and a for loop:
foreach ($compatibility as $compElement) {
$sql = "SELECT * FROM product WHERE ID = '$compElement';";
$em = $this->getDoctrine()->getManager();
$stmt = $em->getConnection()->prepare($sql);
$stmt->execute();
$thisElement = $stmt->fetchAll();
$compArray[] = $thisElement;
}

You can do something like this if you don't want to change how you populate your array:
$result = call_user_func_array(
'array_merge_recursive',
$array
);
Output
array(2) {
[0]=>
array(7) {
["id"]=>
string(1) "1"
["producer"]=>
string(7) "Samsung"
["model"]=>
string(11) "LE22B541C4W"
["category"]=>
string(1) "1"
["production_date"]=>
string(10) "2009-05-08"
["status"]=>
string(12) "Discontinued"
["type"]=>
string(3) "LCD"
}
[1]=>
array(7) {
["id"]=>
string(1) "2"
["producer"]=>
string(7) "Samsung"
["model"]=>
string(6) "P24FHD"
["category"]=>
string(1) "1"
["production_date"]=>
string(10) "0000-00-00"
["status"]=>
string(12) "Discontinued"
["type"]=>
string(3) "LCD"
}
}

Related

How to convert Multidimensional array to Associative array in PhP?

I need to convert the multidimensional array to an associative array.
Please help me to convert the array. Need to remove the keys "sub_code" & "credits" and make the first string as "key" & the second string as "value". I tried a lot of ways but I failed.
Need to convert the below array.
array(9) {
[0]=> array(2)
{
["sub_code"] => string(6) "HS6151"
["credits"] => string(1) "4"
}
[1]=> array(2)
{
["sub_code"] => string(6) "MA6151"
["credits"] => string(1) "4"
}
[2]=> array(2)
{
["sub_code"] => string(6) "PH6151"
["credits"] => string(1) "3"
}
[3]=> array(2)
{
["sub_code"] => string(6) "CY6151"
["credits"] => string(1) "3"
}
[4]=> array(2)
{
["sub_code"] => string(6) "GE6151"
["credits"] => string(1) "3"
}
[5]=> array(2)
{
["sub_code"] => string(6) "GE6152"
["credits"] => string(1) "4"
}
[6]=> array(2)
{
["sub_code"] => string(6) "GE6161"
["credits"] => string(1) "2"
}
[7]=> array(2)
{
["sub_code"] => string(6) "GE6162"
["credits"] => string(1) "2"
}
[8]=> array(2)
{
["sub_code"] => string(6) "GE6163"
["credits"] => string(1) "1"
}
}
Like below.
array(9) {
["HS6151"] => string(1) "4"
["MA6151"] => string(1) "4"
["PH6151"] => string(1) "3"
["CY6151"] => string(1) "3"
["GE6151"] => string(1) "3"
["GE6152"] => string(1) "4"
["GE6161"] => string(1) "2"
["GE6162"] => string(1) "2"
["GE6163"] => string(1) "1"
}
You can use array_column like so:
$array = [
[
'sub_code' => 'HS6151',
'credits' => '4',
],
[
'sub_code' => 'MA6151',
'credits' => '4',
],
];
$result = array_column($array, 'credits', 'sub_code');
print_r($result);
Results in:
Array
(
[HS6151] => 4
[MA6151] => 4
)
Sounds pretty straight forward:
<?php
$input = [
[
"sub_code" => "HS6151",
"credits" => "4"
], [
"sub_code" => "MA6151",
"credits" => "4"
], [
"sub_code" => "PH6151",
"credits" => "3"
], [
"sub_code" => "CY6151",
"credits" => "3"
], [
"sub_code" => "GE6151",
"credits" => "3"
], [
"sub_code" => "GE6152",
"credits" => "4"
], [
"sub_code" => "GE6161",
"credits" => "2"
], [
"sub_code" => "GE6162",
"credits" => "2"
], [
"sub_code" => "GE6163",
"credits" => "1"
]
];
$output = [];
array_walk($input, function($entry) use (&$output) {
$output[$entry["sub_code"]] = $entry["credits"];
});
print_r($output);
The output obviously is:
Array
(
[HS6151] => 4
[MA6151] => 4
[PH6151] => 3
[CY6151] => 3
[GE6151] => 3
[GE6152] => 4
[GE6161] => 2
[GE6162] => 2
[GE6163] => 1
)

unique multidimensional array based on specific multiple keys

I have a multidimensional array which I need to be sorted with unique array based on specific keys. There are same values on item_type_id keys with different partner_id and store_id keys. The result that I expect is when the item_type_id keys have same value and in different partner_id keys with same store_id, it should prefer 10017 value first on partner_id keys.
Example array
[
0 => [
"partner_id" => "10017"
"store_id" => "1000"
"item_type_id" => "2"
"value" => "58"
"category" => "1"
]
1 => [
"partner_id" => "10017"
"store_id" => "1000"
"item_type_id" => "1"
"value" => "63"
"category" => "1"
]
2 => [
"partner_id" => "0"
"store_id" => "1000"
"item_type_id" => "3"
"value" => "29"
"category" => "1"
]
3 => [
"partner_id" => "0"
"store_id" => "1000"
"item_type_id" => "2"
"value" => "58"
"category" => "1"
]
4 => [
"partner_id" => "0"
"store_id" => "1001"
"item_type_id" => "1"
"value" => "65"
"category" => "1"
]
5 => [
"partner_id" => "0"
"store_id" => "1001"
"item_type_id" => "2"
"value" => "58"
"category" => "1"
]
6 => [
"partner_id" => "0"
"store_id" => "1001"
"item_type_id" => "3"
"value" => "29"
"category" => "1"
]
7 => [
"partner_id" => "0"
"store_id" => "1000"
"item_type_id" => "1"
"value" => "65"
"category" => "1"
]
]
Results
[
1000 => [
0 => [
"partner_id" => "10017"
"store_id" => "1000"
"item_type_id" => "2"
"value" => "58"
"category" => "1"
]
1 => [
"partner_id" => "10017"
"store_id" => "1000"
"item_type_id" => "1"
"value" => "63"
"category" => "1"
]
2 => [
"partner_id" => "0"
"store_id" => "1000"
"item_type_id" => "3"
"value" => "29"
"category" => "1"
]
]
1001 => [
0 => [
"partner_id" => "0"
"store_id" => "1001"
"item_type_id" => "1"
"value" => "65"
"category" => "1"
]
1 => [
"partner_id" => "0"
"store_id" => "1001"
"item_type_id" => "2"
"value" => "58"
"category" => "1"
]
2 => [
"partner_id" => "0"
"store_id" => "1001"
"item_type_id" => "3"
"value" => "29"
"category" => "1"
]
]
]
Here is my script
$storeID = [1000,1001];
$createdArray = [];
$previous_item_type_id = "";
$previous_partner_id = "";
foreach($arrays as $array) {
for($i=0; $i<count($storeID); $i++) {
if($array["store_id"] == $storeID[$i]) {
if($array["item_type_id"] != $previous_item_type_id && $array["partner_id"] != $previous_partner_id) {
$createdArray[$storeID[$i]] = [
"partner_id" => $array["partner_id"],
"store_id" => $array["store_id"],
"item_type_id" => $array["item_type_id"],
"value" => $array["value"],
"category" => $array["category"],
];
} else {
$previous_item_type_id = $array["item_type_id"];
$previous_partner_id = $array["partner_id"];
continue;
}
}
}
}
dd($createdArray);
You can use a simple foreach loop to iterate through your array, then use the sub array key store_id to get the key of the final array. push in that final array the value of the current value.
Plus, to remove the duplicated item_type_id, I would write a function that checks if that id already exists in the result.
In example :
$storeID = [1000,1001];
$array = [
0 => [
"partner_id" => "10017",
"store_id" => "1000",
"item_type_id" => "2",
"value" => "58",
"category" => "1"
],
1 => [
"partner_id" => "10017",
"store_id" => "1000",
"item_type_id" => "1",
"value" => "63",
"category" => "1",
],
2 => [
"partner_id" => "0",
"store_id" => "1000",
"item_type_id" => "3",
"value" => "29",
"category" => "1"
],
3 => [
"partner_id" => "0",
"store_id" => "1000",
"item_type_id" => "2",
"value" => "58",
"category" => "1",
],
4 => [
"partner_id" => "0",
"store_id" => "1001",
"item_type_id" => "1",
"value" => "65",
"category" => "1",
],
5 => [
"partner_id" => "0",
"store_id" => "1001",
"item_type_id" => "2",
"value" => "58",
"category" => "1",
],
6 => [
"partner_id" => "0",
"store_id" => "1001",
"item_type_id" => "3",
"value" => "29",
"category" => "1"
],
7 => [
"partner_id" => "0",
"store_id" => "1000",
"item_type_id" => "1",
"value" => "65",
"category" => "1"
]
];
function ItemIdExists($arr, $itemId)
{
foreach ($arr as $subValue)
{
if ($subValue["item_type_id"] == $itemId)
{
return true;
}
}
return false;
}
$result = array();
foreach ($array as $value)
{
$key = $value["store_id"];
if (in_array($key, $storeID))
{
$ItemIdFound = isset($result[$key]) && ItemIdExists($result[$key], $value["item_type_id"]);
if (!$ItemIdFound)
$result[$key][] = $value;
}
}
var_dump($result);
Output
array(2) {
[1000]=>
array(3) {
[0]=>
array(5) {
["partner_id"]=>
string(5) "10017"
["store_id"]=>
string(4) "1000"
["item_type_id"]=>
string(1) "2"
["value"]=>
string(2) "58"
["category"]=>
string(1) "1"
}
[1]=>
array(5) {
["partner_id"]=>
string(5) "10017"
["store_id"]=>
string(4) "1000"
["item_type_id"]=>
string(1) "1"
["value"]=>
string(2) "63"
["category"]=>
string(1) "1"
}
[2]=>
array(5) {
["partner_id"]=>
string(1) "0"
["store_id"]=>
string(4) "1000"
["item_type_id"]=>
string(1) "3"
["value"]=>
string(2) "29"
["category"]=>
string(1) "1"
}
}
[1001]=>
array(3) {
[0]=>
array(5) {
["partner_id"]=>
string(1) "0"
["store_id"]=>
string(4) "1001"
["item_type_id"]=>
string(1) "1"
["value"]=>
string(2) "65"
["category"]=>
string(1) "1"
}
[1]=>
array(5) {
["partner_id"]=>
string(1) "0"
["store_id"]=>
string(4) "1001"
["item_type_id"]=>
string(1) "2"
["value"]=>
string(2) "58"
["category"]=>
string(1) "1"
}
[2]=>
array(5) {
["partner_id"]=>
string(1) "0"
["store_id"]=>
string(4) "1001"
["item_type_id"]=>
string(1) "3"
["value"]=>
string(2) "29"
["category"]=>
string(1) "1"
}
}
}
If I understand the requirements, the desired result will:
group on store_id values and
when item_type_id values collide, the row with a non-zero partner_id value should overwrite a row with a zero partner_id value
Using temporary keys to construct a deeper lookup structure will allow greater efficiency that searching in a loop because key lookups with isset() will always outperform value lookups (with any technique -- even an early return).
After all of the grouping and filtering is done in the loop, flatten the data relating to each store into an associative array of indexed arrays.
Code: (Demo)
$result = [];
foreach ($array as $row) {
if ($row['partner_id'] || !isset($result[$row['store_id']][$row['item_type_id']])) {
$result[$row['store_id']][$row['item_type_id']][$row['partner_id']] = $row;
}
}
var_export(array_map(function($row) { return array_merge(...$row); }, $result));
The snippet above only adds a row into the restructured array if the partner_id is not zero or if the combination of store_id-item_type_id-partner_id has not been encountered before.

PHP foreach loop repeated entries

I need help in order to manipulate a multidimensional array during PHP foreach loop. I have the array below:
$sports = [
[
"id" => "soccer",
"name" => "Football",
"categories" => [
[
"id" => "s1",
"name" => "category 1",
"sportID" => "soccer"
],
[
"id" => "s2",
"name" => "category 2",
"sportID" => "soccer"
],
],
"img" => "/test.png"
],
[
"id" => "tennis",
"name" => "Tennis",
"categories" => [
[
"id" => "t1",
"name" => "category 1",
"sportID" => "tennis"
],
[ "id" => "t2",
"name" => "category 2",
"sportID" => "tennis"
],
],
"img" => "/test.png"
],
];
I have the below foreach in order to take all the sports with the corresponding categories for every sport,
foreach($sports as $s){
$categories = $s['categories'];
foreach($categories as $c){
$cats[] = [
"id" => $c['id'],
"name" => $c['name'],
"sportID" => $s['id'],
];
}
$allCategories[] = $cats;
$data[] = [
"id" => $s['id'],
"name" => $s['name'],
"categories" => $cats,
"img" => $s['img'],
];
$output[] = $data;
}
but the output is not what I expected; instead, I am getting repeated results like the one below:
array(2) {
[0]=>
array(1) {
[0]=>
array(4) {
["id"]=>
string(8) "soccer"
["name"]=>
string(8) "Football"
["categories"]=>
array(2) {
[0]=>
array(3) {
["id"]=>
string(2) "s1"
["name"]=>
string(10) "category 1"
["sportID"]=>
string(8) "soccer"
}
[1]=>
array(3) {
["id"]=>
string(2) "s2"
["name"]=>
string(10) "category 2"
["sportID"]=>
string(8) "soccer"
}
}
["img"]=>
string(9) "/test.png"
}
}
[1]=>
array(2) {
[0]=>
array(4) {
["id"]=>
string(8) "soccer"
["name"]=>
string(8) "Football"
["categories"]=>
array(2) {
[0]=>
array(3) {
["id"]=>
string(2) "s1"
["name"]=>
string(10) "category 1"
["sportID"]=>
string(8) "soccer"
}
[1]=>
array(3) {
["id"]=>
string(2) "s2"
["name"]=>
string(10) "category 2"
["sportID"]=>
string(8) "soccer"
}
}
["img"]=>
string(9) "/test.png"
}
[1]=>
array(4) {
["id"]=>
string(10) "tennis"
["name"]=>
string(8) "Tennis"
["categories"]=>
array(4) {
[0]=>
array(3) {
["id"]=>
string(2) "s-1"
["name"]=>
string(10) "category 1"
["sportID"]=>
string(8) "soccer"
}
[1]=>
array(3) {
["id"]=>
string(2) "s2"
["name"]=>
string(10) "category 2"
["sportID"]=>
string(8) "soccer"
}
[2]=>
array(3) {
["id"]=>
string(2) "t1"
["name"]=>
string(10) "category 1"
["sportID"]=>
string(10) "tennis"
}
[3]=>
array(3) {
["id"]=>
string(2) "t2"
["name"]=>
string(10) "category 2"
["sportID"]=>
string(10) "tennis"
}
}
["img"]=>
string(9) "/test.png"
}
}
}
As you can imagine this is not the correct output, as in the categories of the tennis you can see the categories of the soccer also.
How can I correct my foreach loop in order to get the correct output?
You forget to reset $cats and $data arrays.
<?php
$sports = [
[
"id" => "soccer",
"name" => "Football",
"categories" => [
[
"id" => "s1",
"name" => "category 1",
"sportID" => "soccer"
],
[
"id" => "s2",
"name" => "category 2",
"sportID" => "soccer"
],
],
"img" => "/test.png"
],
[
"id" => "tennis",
"name" => "Tennis",
"categories" => [
[
"id" => "t1",
"name" => "category 1",
"sportID" => "tennis"
],
[ "id" => "t2",
"name" => "category 2",
"sportID" => "tennis"
],
],
"img" => "/test.png"
],
];
foreach($sports as $s){
$categories = $s['categories'];
# before inner loop we need to reset both arrays
$cats = [];
$data = [];
foreach($categories as $c){
$cats[] = [
"id" => $c['id'],
"name" => $c['name'],
"sportID" => $s['id'],
];
}
$allCategories[] = $cats;
$data[] = [
"id" => $s['id'],
"name" => $s['name'],
"categories" => $cats,
"img" => $s['img'],
];
$output[] = $data;
}
echo '<PRE>';
print_r($output);

How to rename anonymous keys in multidimensional array

array:4 [▼
0 => array:2 [▼
0 => "chrysanthemum.jpg"
1 => "http://site.loc/1"
]
1 => array:2 [▼
0 => "desert.jpg"
1 => "http://site.loc/2"
]
2 => array:2 [▼
0 => "hydrangeas.jpg"
1 => "http://site.loc/3"
]
3 => array:2 [▼
0 => "jellyfish.jpg"
1 => "http://site.loc/4"
]
]
How to rename 0 to ['img'] and 1 to ['link'] in each array?
Trying this:
foreach($data as $array){
$array['img']=$array[0];
unset($array[0]);
$array['link']=$array[1];
unset($array[1]);
}
but it doesn't work :c
Does php have a function for this task?
You have two ways to do that.
The first, only put the & in the parameter:
foreach($data as &$array){
$array['img']=$array[0];
unset($array[0]);
$array['link']=$array[1];
unset($array[1]);
}
This will allow change the $array.
Another way is using the array_map:
$data = array_map(function($data) {
return [
'img' => $data['0'],
'link' => $data['1']
];
}, $data);
Response:
array(4) {
[0]=>
array(2) {
["img"]=>
string(17) "chrysanthemum.jpg"
["link"]=>
string(17) "http://site.loc/1"
}
[1]=>
array(2) {
["img"]=>
string(10) "desert.jpg"
["link"]=>
string(17) "http://site.loc/2"
}
[2]=>
array(2) {
["img"]=>
string(14) "hydrangeas.jpg"
["link"]=>
string(17) "http://site.loc/3"
}
[3]=>
array(2) {
["img"]=>
string(13) "jellyfish.jpg"
["link"]=>
string(17) "http://site.loc/4"
}
}
In both cases.
You need to access it via reference, right now you're just changing a copy of the data and not changing the data at all.
foreach($data as &$array){
$array['img'] = $array[0];
$array['link'] = $array[1];
unset($array[0], $array[1]);
}

Build array from specific indices in a multidimensional array

How would I filter out the index of zero which contains the name of the rows being returned from a MySQL query, and then put the results back into a array like the one shown below.
Desired example array:
array:1 [
0 => array:10 [
0 => array:2 [
0 => "2016-01-06"
1 => 10
]
1 => array:2 [
0 => "2016-01-12"
1 => 15
]
]
]
Array that's returned from MySQL query:
array:1 [
0 => array:10 [
0 => array:2 [
0 => "price_1"
1 => 10
]
1 => array:2 [
0 => "day_1"
1 => "2016-01-06"
]
2 => array:2 [
0 => "price_2"
1 => 15
]
3 => array:2 [
0 => "day_2"
1 => "2016-01-12"
]
]
]
You could do something like (assuming $array is your input array with the MySQL results, and $output is our transformed result array):
<?php
$output = array_map(function($value) {
return [$value[1][1], $value[0][1]];
}, $array);
Here's an example using your input:
php > var_dump($array);
array(1) {
[0]=>
array(4) {
[0]=>
array(2) {
[0]=>
string(7) "price_1"
[1]=>
int(10)
}
[1]=>
array(2) {
[0]=>
string(5) "day_1"
[1]=>
string(10) "2016-01-06"
}
[2]=>
array(2) {
[0]=>
string(7) "price_2"
[1]=>
int(15)
}
[3]=>
array(2) {
[0]=>
string(5) "day_2"
[1]=>
string(10) "2016-01-12"
}
}
}
php > $output = array_map(function($value) { return [$value[1][1], $value[0][1]]; }, $array);
php > var_dump($output); array(1) {
[0]=>
array(2) {
[0]=>
string(10) "2016-01-06"
[1]=>
int(10)
}
}
php >

Categories