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
)
)
Related
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!
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I need to convert the data structure of $array1 to $array2. How do I club together the cities belonging to same the uid and title?
$array1 = [array("uid" => "29",
"title" => "Developer",
"city" => "Madrid"),
array("uid" => "29",
"title" => "Developer",
"city" => "Berlin"),
array("uid" => "29",
"title" => "Developer",
"city" => "London"),
array("uid" => "30",
"title" => "Designer",
"city" => "Amsterdam"),
];
$array2 = [array("title":"Developer",
"city" : ["Madrid","Berlin","London"]),
array("title":"Designer",
"city" : ["Amsterdam"])
];
$src = array(
array(
"uid" => "29",
"title" => "Developer",
"city" => "Madrid"
),
array(
"uid" => "29",
"title" => "Developer",
"city" => "Berlin"
),
array(
"uid" => "29",
"title" => "Developer",
"city" => "London"
),
array(
"uid" => "30",
"title" => "Designer",
"city" => "Amsterdam"
),
);
/* placeholder for storing final array */
$out=array();
/* iterate through source array */
foreach( $src as $arr ){
/* for convenience, cast child array as object */
$obj=(object)$arr;
$key=$obj->uid;
/* construct outpur array format & add values from child arrays/objects */
if( !array_key_exists( $key, $out ) )$out[ $key ]=array();
if( !array_key_exists( 'title', $out[ $key ] ) )$out[ $key ]['title']=$obj->title;
if( !array_key_exists( 'city', $out[ $key ] ) ) $out[ $key ]['city']=array();
$out[ $key ]['city'][]=$obj->city;
}
/* this produces an output array keyed by uid */
printf('<pre>%s</pre>',print_r($out,true));
/* If the uid keys are not important and should not appear in output */
$final=array();
foreach( $out as $uid => $child )$final[]=$child;
printf('<pre>%s</pre>',print_r($final,true));
The output of which is:
Array
(
[29] => Array
(
[title] => Developer
[city] => Array
(
[0] => Madrid
[1] => Berlin
[2] => London
)
)
[30] => Array
(
[title] => Designer
[city] => Array
(
[0] => Amsterdam
)
)
)
Array
(
[0] => Array
(
[title] => Developer
[city] => Array
(
[0] => Madrid
[1] => Berlin
[2] => London
)
)
[1] => Array
(
[title] => Designer
[city] => Array
(
[0] => Amsterdam
)
)
)
This probably is what you are looking for:
<?php
$input = [
[
"uid" => "29",
"title" => "Developer",
"city" => "Madrid"
],
[
"uid" => "29",
"title" => "Developer",
"city" => "Berlin"
],
[
"uid" => "29",
"title" => "Developer",
"city" => "London"
],
[
"uid" => "30",
"title" => "Designer",
"city" => "Amsterdam"
]
];
$output = [];
array_walk($input, function($entry) use (&$output) {
if (!array_key_exists($entry["uid"], $output)) {
$output[$entry["uid"]] = [
"title" => $entry["title"],
"city" => [$entry["city"]]
];
} else {
$output[$entry["uid"]]["city"][] = $entry["city"];
}
});
var_dump($output);
The output obviously is:
array(2) {
[29]=>
array(2) {
["title"]=>
string(9) "Developer"
["city"]=>
array(3) {
[0]=>
string(6) "Madrid"
[1]=>
string(6) "Berlin"
[2]=>
string(6) "London"
}
}
[30]=>
array(2) {
["title"]=>
string(8) "Designer"
["city"]=>
array(1) {
[0]=>
string(9) "Amsterdam"
}
}
}
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.
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
)
)
I'm PHP beginner and have a question:
I have a multidimensional associative array:
array(
"X" => array( "x1" => "1", "x2" => "2", "x3" => "3" ),
"Y" => array( "y1" => "1", "y2" => "2", "y3" => "3" ),
"Z" => array( "z1" => "1", "z2" => "2", "z3" => "3" )
)
and need to prepend "" => "" to every element X, Y, Z, so then it will be:
array(
"X" => array( "" => "", "x1" => "1", "x2" => "2", "x3" => "3" ),
"Y" => array( "" => "", "y1" => "1", "y2" => "2", "y3" => "3" ),
"Z" => array( "" => "", "z1" => "1", "z2" => "2", "z3" => "3" )
)
X, Y, Z names are often changed, so I need to get a key name first and then add new value.
I think of using foreach somehow. I'm trying it, but can achieve it.
Thanks
<?php
$temp = array(
"X" => array( "x1" => "1", "x2" => "2", "x3" => "3" ),
"Y" => array( "y1" => "1", "y2" => "2", "y3" => "3" ),
"Z" => array( "z1" => "1", "z2" => "2", "z3" => "3" )
);
$you_array = array();
foreach($temp as $k=>$v){
$v = array_merge([""=>""],$v);
$you_array[$k] = $v;
}
print_r($you_array);
?>
check the following code:
<?php
$temp = array(
"X" => array( "x1" => "1", "x2" => "2", "x3" => "3" ),
"Y" => array( "y1" => "1", "y2" => "2", "y3" => "3" ),
"Z" => array( "z1" => "1", "z2" => "2", "z3" => "3" )
);
$you_array = array();
foreach($temp as $k=>$v){
array_unshift($v, " ");
$you_array[$k] = $v;
}
print_r($you_array);
?>
Out put :
Array (
[X] => Array ( [0] => [x1] => 1 [x2] => 2 [x3] => 3 )
[Y] => Array ( [0] => [y1] => 1 [y2] => 2 [y3] => 3 )
[Z] => Array ( [0] => [z1] => 1 [z2] => 2 [z3] => 3 )
)
You can use array_unshift to add new elements to an array.
As you already mentioned, create a foreach loop and add your new elements to each sub-array:
$new = array("new_key" => "");
foreach ($yourArray as $key => $value)
array_unshift($yourArray[$key], $new);
Be careful: Your new element needs a key value. An empty key (like you mentioned) is not possible. If you just add a new element without a key array("") it will be added with a numerical key (0 => ""). Existing numerical keys will be modified to start counting from zero.
I think this is what you are looking for
[akshay#localhost tmp]$ cat test.php
<?php
$array=array(
"X" => array( "x1" => "1", "x2" => "2", "x3" => "3" ),
"Y" => array( "y1" => "1", "y2" => "2", "y3" => "3" ),
"Z" => array( "z1" => "1", "z2" => "2", "z3" => "3" )
);
// Input
print_r($array);
// & reference
foreach($array as &$sub_array)
{
$sub_array = array(""=>"")+$sub_array;
}
// Output
print_r($array);
?>
Output
[akshay#localhost tmp]$ php test.php
Array
(
[X] => Array
(
[x1] => 1
[x2] => 2
[x3] => 3
)
[Y] => Array
(
[y1] => 1
[y2] => 2
[y3] => 3
)
[Z] => Array
(
[z1] => 1
[z2] => 2
[z3] => 3
)
)
Array
(
[X] => Array
(
[] =>
[x1] => 1
[x2] => 2
[x3] => 3
)
[Y] => Array
(
[] =>
[y1] => 1
[y2] => 2
[y3] => 3
)
[Z] => Array
(
[] =>
[z1] => 1
[z2] => 2
[z3] => 3
)
)