PHP Array manipulation need tips - php

I have arrays in one submission, please see below details:
array(5) {
["ambition_id"]=>
array(2) {
[55]=> string(2) "55"
[60]=> string(2) "60"
}
["target"]=>
array(1) {
[0]=> string(8) "target 1"
[1]=> string(8) "target 2"
}
["strides"]=>
array(1) {
[0]=> string(1) "1"
[1]=> string(1) "1"
}
["date"]=>
array(1) {
[0]=> string(10) "2017-02-08"
[1]=> string(10) "2017-03-08"
}
["frequency"]=>
array(1) {
[0]=> string(1) "1"
[1]=> string(1) "2"
}
}
Actually, I have two tables in mysql, 'ambition' and 'target'. Ambition is a group of targets ('ambition_id' is foreign key in 'target' table). That array will be stored in 'target' table. That's why there is an 'ambition_id'
I've tried many times but failed (using foreach), now I need someone who can give me a help.
By brute force, It's easy! I solved it already but I need "more advanced" array manipulation.
How can I come up into this?
array(2) {
[0] => array('ambition_id' => 55,
'target' => 'target 1',
'strides' => 1,
'date' => '2017-02-08',
'frequency' => 1
),
[1] => array('ambition_id' => 60,
'target' => 'target 2',
'strides' => 2,
'date' => '2017-03-08',
'frequency' => 2)
}
Please do help, many thanks!

You have to pivot your data:
$data = array (
"ambition_id" =>
array (
55 => "55",
60 => "60"
),
"target" =>
array (
0 => "target 1",
1 => "target 2"
),
"strides" =>
array (
0 => "1",
1 => "1"
),
"date" =>
array (
0 => "2017-02-08",
1 => "2017-03-08"
),
"frequency" =>
array (
0 => "1",
1 => "2"
)
);
// pivot data
$pivot = array();
foreach ($data as $datum => $values) {
$value_index = 0;
foreach ($values as $value) {
$pivot[$value_index][$datum] = $value;
$value_index++;
}
}
print_r($pivot);
This assumes you only have two levels of data and that the data is well behaved.

Not the best answer, but it solves your problem
<?php
$array = [
"ambition_id" =>
[
55 => "55",
60 => "60"
],
"target" =>
[
0 => "target 1",
1 => "target 2"
],
"strides" =>
[
0 => "1",
1 => "1"
],
"date" =>
[
0 => "2017-02-08",
1 => "2017-03-08"
],
"frequency" =>
[
0 => "1",
1 => "2"
],
];
$result = array();
foreach ($array as $k => $v) {
foreach ($v as $kk => $vv) {
if ($k == "ambition_id") {
$result[] = array($k => $vv);
} else {
$result[$kk][$k] = $vv;
}
}
}
Here is the test https://3v4l.org/UdHH8

Just use loop the array and user array_values to re-index the loop the inner array and store it into new array like below .
<?php
$new_array =array();
foreach($array as $key1=>$row1 )
{
$ss =array_values($row1);
foreach($ss as $key2=>$row2)
{
$new_array[$key2][$key1]=$row2;
}
}
echo "<pre>";
print_r($new_array);
?>
Output :
Array
(
[0] => Array
(
[ambition_id] => 55
[target] => target 1
[strides] => 1
[date] => 2017-02-08
[frequency] => 1
)
[1] => Array
(
[ambition_id] => 60
[target] => target 2
[strides] => 1
[date] => 2017-03-08
[frequency] => 2
)
)

Related

formatting an array of array that contain similar key value

i have an array of arrays like this one
array(4) {
[0] => array(2) {
["option"] => string(5) "64310"
["choice"] => string(6) "221577"
}
[1] => array(2) {
["option"] => string(5) "64310"
["choice"] => string(6) "221578"
}
[2] => array(2) {
["option"] => string(5) "64305"
["choice"] => string(6) "221538"
}
}
i want to obtain a result like this one
array(2) {
[0] => array(2) {
["option"] => string(5) "64310"
["choices"] => array(2){
["choice"] => string(6) "221577"
["choice"] => string(6) "221578"
}
}
}
how can i proceed, thank you in advance
Something like this will help you achieve the desired result;
<?php
$data = [
[
'option' => '64310',
'choice' => '221577'
],
[
'option' => '64310',
'choice' => '221578'
],
[
'option' => '64305',
'choice' => '221538'
]
];
$res = [];
foreach($data as $d) {
// Check if we've already got this option
// Note the '&' --> Check link below
foreach($res as &$r) {
if (isset($r['option']) && $r['option'] === $d['option']) {
// Add to 'choices'
$r['choices'][] = $d['choice'];
// Skip the rest of both foreach statements
continue 2;
}
}
// Not found, create
$res[] = [
'option' => $d['option'],
'choices' => [ $d['choice'] ],
];
};
print_r($res);
& --> PHP "&" operator
Array
(
[0] => Array
(
[option] => 64310
[choices] => Array
(
[0] => 221577
[1] => 221578
)
)
[1] => Array
(
[option] => 64305
[choices] => Array
(
[0] => 221538
)
)
)
Try online!

Sum of duplicate key values array in PHP [duplicate]

This question already has answers here:
How to sum all column values in multi-dimensional array?
(20 answers)
Closed 9 months ago.
I have an array with duplicate key values. How can I sum all duplicate array key values in another new array?
$array = Array (
"0" => Array ( "2" => 123 ),
"1" => Array ( "4" => 45 ),
"2" => Array ( "3" => 12 ),
"3" => Array ( "5" => 2 ),
"4" => Array ( "2" => 12 ),
"5" => Array ( "4" => 21 ),
"6" => Array ( "2" => 12 ),
"7" => Array ( "3" => 21 ),
"8" => Array ( "2" => 12 ),
"9" => Array ( "3" => 21 ),
"10" => Array ( "2" => 2 ),
"11" => Array ( "4" => 2 ),
"12" => Array ( "2" => 2 ),
"13" => Array ( "4" => 2 ),
"14" => Array ( "3" => 12 ),
"15" => Array ( "4" => 12 ),
"16" => Array ( "2" => 12 ),
"17" => Array ( "2" => 12 ),
"18" => Array ( "4" => 12 ),
"19" => Array ( "3" => 12 ),
"20" => Array ( "2" => 15 ),
"21" => Array ( "4" => 21 ),
);
Output will looks like
$newArray = Array
(
[2] => 202
[3] => 78
[4] => 115
[5] => 2
)
You can use array_sum and array_column to get the sums of each.
First we have to get all the keys then sum them with array_sum and array_column.
$arr = Array (
"0" => Array ( "2" => 123 ),
"1" => Array ( "4" => 45 ),
"2" => Array ( "3" => 12 ),
"3" => Array ( "5" => 2 ),
"4" => Array ( "2" => 12 ),
"5" => Array ( "4" => 21 ),
"6" => Array ( "2" => 12 ),
"7" => Array ( "3" => 21 ),
"8" => Array ( "2" => 12 ),
"9" => Array ( "3" => 21 ),
"10" => Array ( "2" => 2 ),
"11" => Array ( "4" => 2 ),
"12" => Array ( "2" => 2 ),
"13" => Array ( "4" => 2 ),
"14" => Array ( "3" => 12 ),
"15" => Array ( "4" => 12 ),
"16" => Array ( "2" => 12 ),
"17" => Array ( "2" => 12 ),
"18" => Array ( "4" => 12 ),
"19" => Array ( "3" => 12 ),
"20" => Array ( "2" => 15 ),
"21" => Array ( "4" => 21 ),
);
// find all subarray keys (2,3,4,5)
foreach($arr as $subarr){
$keys[] = key($subarr);
}
// remove duplicate keys
$keys = array_unique($keys);
// sum values with same key from $arr and save to $sums
foreach($keys as $key){
$sums[$key] = array_sum(array_column($arr,$key));
}
var_dump($sums);
https://3v4l.org/F3RJr
The code can be made shorter like this:
foreach($arr as $subarr){
$key = key($subarr);
if(!isset($sums[$key])){
$sums[$key] = array_sum(array_column($arr,$key));
}
}
var_dump($sums);
but I'm not sure it's faster. Maybe...
You can use array_walk_recursive()
$result = [];
array_walk_recursive($array, function($v, $k) use (&$result) {
if (!isset($result[$k])) {
$result[$k] = $v;
} else {
$result[$k] += $v;
}
});
print_r($result);
Check the below code.
$output = array();
$keyarray = array();
foreach($arr as $key => $val){
if(is_array($val)){
$key = key($val);
if(in_array($key,$keyarray)) {
$output[$key] = $output[$key]+$val[$key];
} else {
$keyarray[] = $key;
$output[$key] = $val[$key];
}
}
}
print_r($output);
print_r($output); will give you the expected result.

Array Restructuring

I have the following query result:
Array
(
[0] => stdClass Object
(
[TreatmentLog_ID] => 131
[DateAdministered] => 2016-07-15
[Notes] =>
[Treatment_ID] => 144
[AmountAdministered] => 1.5
[Injectable_ID] => 2
[InjectableName] => Baytril
)
[1] => stdClass Object
(
[TreatmentLog_ID] => 133
[DateAdministered] => 2016-07-12
[Notes] =>
[Treatment_ID] => 146
[AmountAdministered] => 1.2
[Injectable_ID] => 20
[InjectableName] => Vitamin C
)
[2] => stdClass Object
(
[TreatmentLog_ID] => 133
[DateAdministered] => 2016-07-12
[Notes] =>
[Treatment_ID] => 147
[AmountAdministered] => 1.3
[Injectable_ID] => 21
[InjectableName] => Vitamin E
)
)
I'd like to be able to restructure the array into something like this:
Array
(
[0] => stdClass Object
(
[TreatmentLog_ID] => 131
[DateAdministered] => 2016-07-15
[Notes] =>
[Treatments] => Array
(
[0] => stdClass Object
(
[Treatment_ID] => 144
[AmountAdministered] => 1.5
[Injectable_ID] => 2
[InjectableName] => Baytril
)
)
)
[1] => stdClass Object
(
[TreatmentLog_ID] => 133
[DateAdministered] => 2016-07-12
[Notes] =>
[Treatments] => Array
(
[0] => stdClass Object
(
[Treatment_ID] => 146
[AmountAdministered] => 1.2
[Injectable_ID] => 20
[InjectableName] => Vitamin C
)
[1] => stdClass Object
(
[Treatment_ID] => 147
[AmountAdministered] => 1.3
[Injectable_ID] => 21
[InjectableName] => Vitamin E
)
)
)
)
Notice how the second array looks merges the InjectableName, AmountAdministered, Injectable_ID, and Treatment_ID into the array Treatments if the TreatmentLog_ID is a match. Typically working with arrays isn't a problem, but this one has me stumped. Also I cannot change the query.
How could I pull this off in PHP?
The solution using isset and array_values functions:
// $arr is your initial array
$result = [];
foreach ($arr as $obj) {
$innerObj = (object)[ 'Treatment_ID' => $obj->Treatment_ID, 'AmountAdministered' => $obj->AmountAdministered,
'Injectable_ID' => $obj->Injectable_ID, 'InjectableName' => $obj->InjectableName ];
if (!isset($result[$obj->TreatmentLog_ID])) {
$result[$obj->TreatmentLog_ID] = (object)[
'TreatmentLog_ID' => $obj->TreatmentLog_ID,
'DateAdministered' => $obj->DateAdministered,
'Notes' => $obj->Notes,
'Treatments' => [$innerObj]
];
} else {
$result[$obj->TreatmentLog_ID]->Treatments[] = $innerObj;
}
}
$result = array_values($result);
print_r($result); // will output the expected result
Try this.
We use array_filter() to fetch all of the elements from the $inputArray with the same TreatmentLog_ID. Then we transform those filtered elements with array_map(). We have to create a copy of each element with clone, since they're objects and objects are passed by reference. Then we unset() the keys we don't need in the copy.
<?php
$inputArray = [
0 => (object) [
'TreatmentLog_ID' => 131,
'DateAdministered' => '2016-07-15',
'Notes' => '',
'Treatment_ID' => 144,
'AmountAdministered' => 1.5,
'Injectable_ID' => 2,
'InjectableName' => 'Baytril'
],
1 => (object) [
'TreatmentLog_ID' => 133,
'DateAdministered' => '2016-07-12',
'Notes' => '',
'Treatment_ID' => 146,
'AmountAdministered' => 1.2,
'Injectable_ID' => 20,
'InjectableName' => 'Vitamin C'
],
2 => (object) [
'TreatmentLog_ID' => 133,
'DateAdministered' => '2016-07-12',
'Notes' => '',
'Treatment_ID' => 147,
'AmountAdministered' => 1.3,
'Injectable_ID' => 21,
'InjectableName' => 'Vitamin E'
],
];
$transformedArray = [];
foreach ($inputArray as $key => $value)
{
$transformedArray[$key] = [
'TreatmentLog_ID' => $value->TreatmentLog_ID,
'DateAdministered' => $value->DateAdministered,
'Notes' => $value->Notes,
'Treatments' => array_map(
function ($v) {
$copy = clone $v;
unset($copy->Notes);
unset($copy->DateAdministered);
unset($copy->TreatmentLog_ID);
return $copy;
},
array_filter($inputArray, function ($v) use ($value) {
return $v->TreatmentLog_ID == $value->TreatmentLog_ID;
})
)
];
}
var_dump($transformedArray);
This gives me:
array(3) {
[0]=>
array(4) {
["TreatmentLog_ID"]=>
int(131)
["DateAdministered"]=>
string(10) "2016-07-15"
["Notes"]=>
string(0) ""
["Treatments"]=>
array(1) {
[0]=>
object(stdClass)#5 (4) {
["Treatment_ID"]=>
int(144)
["AmountAdministered"]=>
float(1.5)
["Injectable_ID"]=>
int(2)
["InjectableName"]=>
string(7) "Baytril"
}
}
}
[1]=>
array(4) {
["TreatmentLog_ID"]=>
int(133)
["DateAdministered"]=>
string(10) "2016-07-12"
["Notes"]=>
string(0) ""
["Treatments"]=>
array(2) {
[1]=>
object(stdClass)#6 (4) {
["Treatment_ID"]=>
int(146)
["AmountAdministered"]=>
float(1.2)
["Injectable_ID"]=>
int(20)
["InjectableName"]=>
string(9) "Vitamin C"
}
[2]=>
object(stdClass)#7 (4) {
["Treatment_ID"]=>
int(147)
["AmountAdministered"]=>
float(1.3)
["Injectable_ID"]=>
int(21)
["InjectableName"]=>
string(9) "Vitamin E"
}
}
}
[2]=>
array(4) {
["TreatmentLog_ID"]=>
int(133)
["DateAdministered"]=>
string(10) "2016-07-12"
["Notes"]=>
string(0) ""
["Treatments"]=>
array(2) {
[1]=>
object(stdClass)#8 (4) {
["Treatment_ID"]=>
int(146)
["AmountAdministered"]=>
float(1.2)
["Injectable_ID"]=>
int(20)
["InjectableName"]=>
string(9) "Vitamin C"
}
[2]=>
object(stdClass)#9 (4) {
["Treatment_ID"]=>
int(147)
["AmountAdministered"]=>
float(1.3)
["Injectable_ID"]=>
int(21)
["InjectableName"]=>
string(9) "Vitamin E"
}
}
}
}
Let's break down how we build Treatments:
'Treatments' => array_map(
function ($v) {
$copy = clone $v;
unset($copy->Notes);
unset($copy->DateAdministered);
unset($copy->TreatmentLog_ID);
return $copy;
},
array_filter($inputArray, function ($v) use ($value) {
return $v->TreatmentLog_ID == $value->TreatmentLog_ID;
})
)

Replace multidimensional array that has the same key values [duplicate]

This question already has answers here:
Merge two 2d arrays by shared column value
(6 answers)
Closed 2 months ago.
I have this array that I have to replace the values according to their id. below is the Original Array:
[
0 => [
"id" => "70"
"color" => "red"
]
1 => [
"id" => "65"
"color" => "blue"
]
2 => [
"id" => "66"
"color" => "black"
]
3 => [
"id" => "73"
"color" => "red"
]
]
And this is the array that I need to insert and replace the array that has the same id in the original array:
0 => [
"id" => "65"
"color" => "white"
]
1 => [
"id" => "66"
"color" => "gold"
]
]
What I am trying to achieve is something like this:
[
0 => [
"id" => "70"
"color" => "red"
]
1 => [
"id" => "65"
"color" => "white"
]
2 => [
"id" => "66"
"color" => "gold"
]
3 => [
"id" => "73"
"color" => "red"
]
]
Simple solution with array_column and array_walk functions:
// $arr1 is the original array
// $arr2 is the replacing array
$colours = array_column($arr2, "color", "id");
array_walk($arr1, function(&$v) use($colours){
if (array_key_exists($v["id"],$colours)) {
$v["color"] = $colours[$v["id"]];
}
});
print_r($arr1);
The output:
Array
(
[0] => Array
(
[id] => 70
[color] => red
)
[1] => Array
(
[id] => 65
[color] => white
)
[2] => Array
(
[id] => 66
[color] => gold
)
[3] => Array
(
[id] => 73
[color] => red
)
)
http://php.net/manual/ru/function.array-column.php
http://php.net/manual/ru/function.array-walk.php
Try this code:
<?php
$original = [
0 => [
"id" => "70",
"color" => "red" ,
],
1 => [
"id" => "65",
"color" => "blue",
],
2 => [
"id" => "66",
"color" => "black",
],
3 => [
"id" => "73",
"color" => "red",
]
];
$toReplace = [0 => [
"id" => "65",
"color" => "white" ,
],
1 => [
"id" => "66",
"color" => "gold",
]
];
function getColorByKey($key, $toReplace)
{
$result = null;
foreach($toReplace as $k => $value)
{
if($value['id'] == $key)
$result = $value['color'];
}
return $result;
}
foreach($original as $key => $value)
{
$newColor = getColorByKey($value['id'], $toReplace);
$original[$key]['color'] = $newColor !== null ? $newColor : $original[$key]['color'];
}
var_dump($original);
Output of var_dump:
array(4) {
[0]=>
array(2) {
["id"]=>
string(2) "70"
["color"]=>
string(3) "red"
}
[1]=>
array(2) {
["id"]=>
string(2) "65"
["color"]=>
string(5) "white"
}
[2]=>
array(2) {
["id"]=>
string(2) "66"
["color"]=>
string(4) "gold"
}
[3]=>
array(2) {
["id"]=>
string(2) "73"
["color"]=>
string(3) "red"
}
}
There is a function getColorByKey($key, $toReplace) which is used in foreach loop, where $key is id index, and $toReplace is your second array.
// $array1 = original array
// $array2 = second array
foreach ($array1 as $key1 => $value)
{
$new[$value['id']] = $key1;
}
foreach ($array2 as $value)
{
if (array_key_exists($value['id'], $new))
{
$key2 = $new[$value['id']];
$array1[$key2]['color'] = $value['color'];
}
else
{
$array1[] = array('id' => $value['id'], 'color' => $value['color']);
// if this color not present, then it adds this to the original array
}
}
echo '<pre>'; print_r($array1);
Output:
Array
(
[0] => Array
(
[id] => 70
[color] => red
)
[1] => Array
(
[id] => 65
[color] => white
)
[2] => Array
(
[id] => 66
[color] => gold
)
[3] => Array
(
[id] => 73
[color] => red
)
)

How to insert data into php multi dimensional array

This one should be straight forward, but I am having issues as I have not worked with arrays that much.
So I am try to insert data into a 3 dimensional array, this is the structure of my 3 dimensional array:
Array
(
[data] => Array
(
[0] => Array
(
[name] => name
[by] => by
[imgUrl] => imgUrl
[linkUrl] => linkUrl
[date] => date
)
[1] => Array
(
[name] => name
[by] => by
[imgUrl] => imgUrl
[linkUrl] => linkUrl
[date] => date
)
)
)
I am trying to push the existing array downwards, the existing [0] becomes [1], ect. While the new [0] will be the posted data from a form.
I have tried array_push, array_splice, array_merge, but all to no avail.
if I understood you correctly...
here's a fiddle.
$multi = array(
"data" =>array(
array(
'something1' => 'something else',
'something0' => 'something else',
'something345' => 'something else'
),
array(
'something1' => 'something else',
'something0' => 'something else',
'something345' => 'something else'
),
)
);
$new = array(
'something1' => 'something else',
'something0' => 'something else',
'something345' => 'something else'
);
array_push($multi['data'], $new);
print_r($multi);
You are looking for the array_unshift function:
array_unshift($arr["data"], $new);
Test script:
$arr = Array(
"data" => Array(
Array(
"name" => "name",
"by" => "by",
"imgUrl" => "imgUrl",
"linkUrl" => "linkUrl",
"date" => "date"
)
,Array(
"name" => "lastname",
"by" => "by",
"imgUrl" => "imgUrl",
"linkUrl" => "linkUrl",
"date" => "date"
)
)
);
$new = Array(
"name" => "newname",
"by" => "newby",
"imgUrl" => "newimgUrl",
"linkUrl" => "newlinkUrl",
"date" => "newdate"
);
array_unshift($arr["data"], $new);
print_r ($arr);
Output shows that new element pushes the other elements down:
array(1) {
["data"]=> array(3) {
[0]=> array(5) {
["name"]=> string(7) "newname"
["by"]=> string(5) "newby"
["imgUrl"]=> string(9) "newimgUrl"
["linkUrl"]=> string(10) "newlinkUrl"
["date"]=> string(7) "newdate"
}
[1]=> array(5) {
["name"]=> string(4) "name"
["by"]=> string(2) "by"
["imgUrl"]=> string(6) "imgUrl"
["linkUrl"]=> string(7) "linkUrl"
["date"]=> string(4) "date"
}
[2]=> array(5) {
["name"]=> string(9) "firstname"
["by"]=> string(2) "by"
["imgUrl"]=> string(6) "imgUrl"
["linkUrl"]=> string(7) "linkUrl"
["date"]=> string(4) "date"
}
}
}

Categories