Merging arrays PHP - php

I have two arrays of data:
array(2) {
["12:15"]=>
string(84) "http://form.horseracing.betfair.com/horse-racing/010108/Catterick_Bridge-GB-Cat/1215"
["12:20"]=>
string(77) "http://form.horseracing.betfair.com/horse-racing/010108/Southwell-GB-Sou/1220"
}
and
array(2) {
["12:15"]=>
string(90) "http://www.racingpost.com/horses/result_home.sd?race_id=446323&r_date=2008-01-01&popup=yes"
["12:20"]=>
string(90) "http://www.racingpost.com/horses/result_home.sd?race_id=446250&r_date=2008-01-01&popup=yes"
}
I want to merge these based on time, so I end up with an array of values where times in both arrays match only.
array(2) {
["12:15"]=>
array(2) {
[0]=>
string(84) "http://form.horseracing.betfair.com/horse-racing/010108/Catterick_Bridge-GB-Cat/1215"
[1]=>
string(90) "http://www.racingpost.com/horses/result_home.sd?race_id=446323&r_date=2008-01-01&popup=yes"
}
["12:20"]=>
array(2) {
[0]=>
string(77) "http://form.horseracing.betfair.com/horse-racing/010108/Southwell-GB-Sou/1220"
[1]=>
string(90) "http://www.racingpost.com/horses/result_home.sd?race_id=446250&r_date=2008-01-01&popup=yes"
}
}

Wouldn't the following do trick?
$arr1 = array('time' => '14:00', 'rp' => 'blah');
$arr2 = array('time' => '14:00', 'bf' => 'yadda');
if ($arr1['time'] === $arr2['time']) {
$mergedArray = array_merge($arr1, $arr2);
}

$result = array();
foreach ($all_arrays as $a) {
if (!isset($result[$a["time"]])) {
$result[$a["time"]] = array();
}
$result[$a["time"]] = array_merge($result[$a["time"]], $a);
}
$result = array_values($result);

I'm assuming you have any number of these time arrays. It's probably a good idea to store the array like this:
$times = array(
'14:00' => array(...),
'15:00' => array(...),
etc...
);
$temp = array();
foreach($time_arrays as $time_array) {
if(isset($temp[$time_array['time'])) {
$temp[$time_array['time'] = array_merge(temp[$time_array['time'], $time_array);
}
else {
$temp[$time_array['time'] = $time_array;
}
}

$arr1 = array('time' => '14:00', 'rp' => 'blah');
$arr2 = array('time' => '14:00', 'bf' => 'yadda');
$arr3 = $arr1 + $arr2 ;
var_dump( $arr3 ) ;
Gives
array
'time' => string '14:00' (length=5)
'rp' => string 'blah' (length=4)
'bf' => string 'yadda' (length=5)

Using a combination of the answers on offer and some extra Google foo, solved it using the following:
$c = array_merge_recursive($a, $b);

Related

how to split a string and build an associative array php?

How to split a string in PHP ? For example, if i have the string like
Array([0] => "1=>10,2=>9,3=>7,1=>9,2=>8,3=>7");
how can i get
Array([0] => 1=>10,2=>9,3=>7 [1] => 1=>9,2=>8,3=>7);
and later i want to build an associative array like for example,
$ratings = array(6533 => ['Build Quality' => [1=>10,2=>9,3=>7],
'Versatility' => [1=>9,2=>8,3=>7],
'value' => [1=>9.5,2=>7,3=>6]]);
//takes the current post id and returns an product ratings array
function get_ratings($current_post_id){
$product_post = get_post($current_post_id);
preg_match_all("/\[v360_product_table\s.*?\]/", $product_post>post_content, $product_elements);
$product_elements = $product_elements[0][0];
preg_match_all('/"([^"]+)"/', $product_elements, $parameters);
$product_params = $parameters[0][0];
$rating_params = preg_split('","', $product_params);
$rating_factors = str_replace('"', '', $rating_params);
$b = print_r($rating_factors);
/* output: Array ( [0] => Build Quality [1] => Versatality [2] => Adoptability) */
$product_rank = $parameters[0][1];
/* output: Array ( [0] => 1=>10,2=>9,3=>7,1=>9,2=>8,3=>7 ) */
$rank_split = preg_split('"**have to split it here**"', $product_rank);
$rank_values = str_replace('"', '', $rank_split);
$assoc_array = array_combine($rating_factors, $rank_values);
/* needs to construct an array like '$ratings' */
$ratings = array(6533 => ['Build Quality' => [1 => 10, 2 => 8, 3 => 7],
'Versatility' => [1 => 9, 2 => 9, 3 => 8], 'Value' => [1 => 10, 2 => 8,3 => 8]]);
return $ratings[$current_post_id];
}
From your examples, I'm guessing you want to split the string by commas followed by the number 1. To do this, you can use preg_split() with a positive lookahead:
$string = "1=>10,2=>9,3=>7,1=>9,2=>8,3=>7";
$split = preg_split('/,(?=1\b)/', $string);
var_dump($split);
Gives:
array(2) {
[0]=>
string(15) "1=>10,2=>9,3=>7"
[1]=>
string(14) "1=>9,2=>8,3=>7"
}
This function will parse out the whole string into a nested array:
function split_string($string)
{
$split = array();
foreach (preg_split('/,(?=1\b)/', $string) as $row => $part1) {
foreach (explode(',', $part1) as $part2) {
list($key, $value) = explode('=>', $part2, 2);
$split[$row][$key] = $value;
}
}
return $split;
}
Tested as follows (in php 5.6):
$string = "1=>10,2=>9,3=>7,1=>9,2=>8,3=>7";
$split = split_string($string);
var_dump($split);
Gives this output:
array(2) {
[0]=>
array(3) {
[1]=>
string(2) "10"
[2]=>
string(1) "9"
[3]=>
string(1) "7"
}
[1]=>
array(3) {
[1]=>
string(1) "9"
[2]=>
string(1) "8"
[3]=>
string(1) "7"
}
}
You could then use array_combine() for example to merge in the names:
$string = "1=>10,2=>9,3=>7,1=>9,2=>8,3=>7";
$split = split_string($string);
var_dump(array_combine(array('Build Quality', 'Versatility'), $split));

Global array in php issues

I've found some very helpful answers but still have some problems.
I want to put different rows in global array, WITHOUT removing the other rows.
<?php
global $global_arr;
function first() {
///some code
global $global_arr;
$global_arr[] = array('first' =>
array('1' , '1', '1'));
}
function second() {
///some code
global $global_arr;
$global_arr[] = array('second' =>
array('2' , '2', '2'));
}
function third() {
///some code
global $global_arr;
$global_arr[] = array('third' =>
array('3' , '3', '3'));
}
first();
second();
third();
print_r($global_arr);
I want every of the functions to index the array and add rows respectevly
Thank you in advance!
Edit :
Thank to your help here is the working version :
function first($arr) {
$arr[] = array('first' =>
array(1, 1, 1));
return $arr;
}
function second($arr) {
$arr[] = array('second' =>
array(2, 2, 2));
return $arr;
}
$arr = array();
$arr = first($arr);
$arr = second($arr);
print_r($arr);
Output :
Array ( [0] => Array ( [first] => Array ( [0] => 1 [1] => 1 [2] => 1 ) ) [1] => Array ( [second] => Array ( [0] => 2 [1] => 2 [2] => 2 ) ) )
Any ideas how to be only :
Array ( [first] => Array ( [0] => 1 [1] => 1 [2] => 1) , [second] => Array([0] => 2, [1] => 2, [2] => 2))
?
$global_arr['third'][] = array('3.1' , '3.2', '3.3');
I don't get it - it's the same in/for all three functions.
BTW, I would use only one function like:
<?php
// $arg1 = "one", "two" or "three"
// $arg2 = ARRAY("data1.1", "data1.2", "data1.3") {
function myfunc($arg1, $arg2) {
if (!isset($my_arr)) { static $my_arr = ARRAY(); }
$my_arr[$arg1][] = $arg2;
return $my_arr; // Or code a getter and setter function
}
// Call, as often as you want - like:
myfunc('one', ARRAY('1.1', '1.2','1.3'));
myfunc('two', ARRAY('2.1', '2.2','2.3'));
$arr = myfunc('one', ARRAY('1.4', '1.5','1.6'));
print '<pre>';
var_dump($arr);
print '</pre>';
/* result:
array(2) {
["one"]=>
array(2) {
[0]=>
array(3) {
[0]=>
string(3) "1.1"
[1]=>
string(3) "1.2"
[2]=>
string(3) "1.3"
}
[1]=>
array(3) {
[0]=>
string(3) "1.4"
[1]=>
string(3) "1.5"
[2]=>
string(3) "1.6"
}
}
["two"]=>
array(1) {
[0]=>
array(3) {
[0]=>
string(3) "2.1"
[1]=>
string(3) "2.2"
[2]=>
string(3) "2.3"
}
}
}
*/
?>
Why you want to use global variable? You can simply write
function first($arr) {
$arr[] = array('first' =>
array('3' , '3', '3'));
return $arr;
}
function second($arr) {
$arr[] = array('second' =>
array('3' , '3', '3'));
return $arr;
}
function third($arr) {
$arr[] = array('third' =>
array('3' , '3', '3'));
return $arr;
}
$arr = array();
$arr = first($arr);
$arr = second($arr);
$arr = third($arr);

PHP Array Merge two Arrays on same key

I am trying to merge the following two arrays into one array, sharing the same key:
First Array:
array(3) {
[0]=>
array(1) {
["Camera1"]=>
string(14) "192.168.101.71"
}
[1]=>
array(1) {
["Camera2"]=>
string(14) "192.168.101.72"
}
[2]=>
array(1) {
["Camera3"]=>
string(14) "192.168.101.74"
}
}
Second Array:
array(3) {
[0]=>
array(1) {
["Camera1"]=>
string(2) "VT"
}
[1]=>
array(1) {
["Camera2"]=>
string(2) "UB"
}
[2]=>
array(1) {
["Camera3"]=>
string(2) "FX"
}
}
As you can see, they share the same key (Camera1, Camera2, Camera3, etc..)
Here is what I have tried:
$Testvar = array_merge($NewArrayCam,$IpAddressArray);
foreach ($Testvar AS $Newvals){
$cam = array();
foreach($Newvals AS $K => $V){
$cam[] = array($K => $V);
}
Ideally I would look to format the two arrays in such a way that array_merge_recursive would simply merge the arrays without too much fuss.
However I did come up with a solution that used array_map.
$array1 = array(
array("Camera1" => "192.168.101.71"),
array("Camera2" => "192.168.101.72"),
array("Camera3" => "192.168.101.74"),
);
$array2 = array(
array("Camera1" => "VT"),
array("Camera2" => "UB"),
array("Camera3" => "FX")
);
$results = array();
array_map(function($a, $b) use (&$results) {
$key = current(array_keys($a));
$a[$key] = array('ip' => $a[$key]);
// Obtain the key again as the second array may have a different key.
$key = current(array_keys($b));
$b[$key] = array('name' => $b[$key]);
$results += array_merge_recursive($a, $b);
}, $array1, $array2);
var_dump($results);
The output is:
array (size=3)
'Camera1' =>
array (size=2)
'ip' => string '192.168.101.71' (length=14)
'name' => string 'VT' (length=2)
'Camera2' =>
array (size=2)
'ip' => string '192.168.101.72' (length=14)
'name' => string 'UB' (length=2)
'Camera3' =>
array (size=2)
'ip' => string '192.168.101.74' (length=14)
'name' => string 'FX' (length=2)
Try to use array_merge_recursive.
Use array_merge_recursive :
Convert all numeric key to strings, (make is associative array)
$result = array_merge_recursive($ar1, $ar2);
print_r($result);
Ref : http://php.net/array_merge_recursive
For your nesting level will be enough this:
$sumArray = array_map(function ($a1, $b1) { return $a1 + $b1; }, $array1, $array2);
For deeper nesting it wont work.
If both arrays have the same numbers of levels and keys this should work:
$array3 = array();
foreach ($array1 as $key1 => $value1) {
// store IP
$array3['Camera'.$key1]['IP'] = $value['Camera'.$key1];
// store type of cam
$array3['Camera'.$key1]['Type'] = $array2[$key]['Camera'.$key1];
}
At the end $array3 should be something like:
$array3 = array {
["Camera1"] => {['IP'] => "192.168.101.71", ['Type'] => "VT" }
["Camera2"] => {['IP'] => "192.168.101.72", ['Type'] => "UB" }
["Camera3"] => {['IP'] => "192.168.101.74", ['Type'] => "FX" }
}
this would be one of the soluion:
function array_merge_custom($array1,$array2) {
$mergeArray = [];
$array1Keys = array_keys($array1);
$array2Keys = array_keys($array2);
$keys = array_merge($array1Keys,$array2Keys);
foreach($keys as $key) {
$mergeArray[$key] = array_merge_recursive(isset($array1[$key])?$array1[$key]:[],isset($array2[$key])?$array2[$key]:[]);
}
return $mergeArray;
}
$array1 = array(
array("Camera1" => "192.168.101.71"),
array("Camera2" => "192.168.101.72"),
array("Camera3" => "192.168.101.74"),
);
$array2 = array(
array("Camera1" => "VT"),
array("Camera2" => "UB"),
array("Camera3" => "FX")
);
echo '<pre>';
print_r(array_merge_custom($array1 , $array2));
The main problem are the arrays. Because of the way they are structured it becomes unnecessarily complicated to merge them. It they simply were normal associative arrays (i.e. array('Camera1' => 'VT') then it would be effortless to merge them.
I would suggest that you figure out how to format the data in such a way as to make it easier to work with.
This is a quick and dirty way of merging the two arrays. It takes one "camera" from one array, and then tries to find the corresponding "camera" in the other array. The function only uses the "cameras" in the $ips array, and only uses matching CameraN keys.
$ips = array(
array('Camera1' => '192.168.101.71'),
array('Camera2' => '192.168.101.72'),
array('Camera3' => '192.168.101.74'),
);
$names = array(
array('Camera1' => 'VT'),
array('Camera2' => 'UB'),
array('Camera3' => 'FX'),
);
function combineCameras($ips, $names) {
$output = array();
while ($ip = array_shift($ips)) {
$ident = key($ip);
foreach ($names as $key => $name) {
if (key($name) === $ident) {
$output[$ident] = array(
'name' => array_shift($name),
'ip' => array_shift($ip),
);
unset($names[$key]);
}
}
}
return $output;
}
var_dump(combineCameras($ips, $names));
Something like this should work:
$array1 = array(array("Camera1" => "192.168.101.71"), array("Camera2" => "192.168.101.72"), array("Camera3" => "192.168.101.74"));
$array2 = array(array("Camera1" => "VT"), array("Camera2" => "UB"), array("Camera3" => "FX"));
$results = array();
foreach($array1 as $key => $array){
foreach($array as $camera => $value){
$results[$camera]['ip'] = $value;
}
}
foreach($array2 as $key => $array){
foreach($array as $camera => $value){
$results[$camera]['name'] = $value;
}
}
print_r($results);
This worked for me.
I joined two arrays with the same keys
$array1 = ArrayUtils::merge($array1, $array2);
If you need preserve NumericKey, use
$array1 = ArrayUtils::merge($array1, $array2, true);
You could convert all numeric keys to strings and use array_replace_recursive which:
merges the elements of one or more arrays together so that the values of one are appended to the end of the previous one. It returns the resulting array.
Example
$arr1 = [
'rate' => 100
];
$arr2 = [
'rate' => 100,
'name' => 'Best Name In Town',
];
print_r(array_replace_recursive($arr1, $arr2));
Output
Array
(
[rate] => 100
[name] => Best Name In Town
)

Check for differnent values between new and old arrays PHP

I have an array of values that will get updated periodically. When the array is updated, I want to perform an action using the new values in the updated array.
$old_node->field_name[0]['value'] = 'red'
$old_node->field_name[1]['value'] = 'yellow'
$old_node->field_name[2]['value'] = 'blue'
$updated_node->field_name[0]['value'] = 'green',
$updated_node->field_name[1]['value'] = 'red',
$updated_node->field_name[2]['value'] ='purple',
$updated_node->field_name[3]['value'] = 'blue',
So the values of 'green' and 'purple' are the new values in the new array. I need to run each of the values that are ADDED to the new array through a function. Something like:
foreach(of the newly added values that are in the new array){
//do stuff;
}
Some values may be deleted when the array is updated, so the the key=>value pairs could change.
I've tried:
foreach($updated_node->field_name as $new_value){
if(!in_array($new_value['value'], $old_node->field_name) && $new_value['value'] !== NULL){
//Do stuff;
}
}
But that doesn't work. I've also tried picking out new values with array_diff and array_intersect, but that's not working either.
use array_diff()
$old_array = array(
0 => 'red',
1 =>'yellow',
2 => 'blue'
);
$new_array = array(
0 => 'green',
1 => 'red',
2 =>'purple',
4 => 'blue'
);
$diff = array_diff($new_array, $old_array);
print_r($diff);
/*
Array
(
[0] => green
[2] => purple
)
*/
for your new code
$old_node->field_name[0]['value'] = 'red';
$old_node->field_name[1]['value'] = 'yellow';
$old_node->field_name[2]['value'] = 'blue';
$updated_node->field_name[0]['value'] = 'green';
$updated_node->field_name[1]['value'] = 'red';
$updated_node->field_name[2]['value'] = 'purple';
$updated_node->field_name[3]['value'] = 'blue';
$diff = array();
foreach($updated_node->field_name as $num => $field){
$tmpval = false;
foreach($old_node->field_name as $old){
if($field['value'] == $old['value']){
$tmpval = true;
}
}
if(!$tmpval){
$diff[$num] = $field['value'];
}
}
print_r($diff);
/*
Array
(
[0] => green
[2] => purple
)
*/
$old_array = array(
[0] => 'red',
[1] =>'yellow',
[2] => 'blue',
);
$new_array = array(
[0] => 'green',
[1] => 'red',
[2] =>'purple',
[4] => 'blue',
);
$diff = array_diff($new_array, $old_array);
var_dump($diff);
That results in
array(2) {
[0]=>
string(5) "green"
[2]=>
string(6) "purple"
}
which is the correct (expected) result.
Here is a simple function to load up two arrays with the added and removed values:
function loadArrayDifferences($before, $after, &$added, &$removed) {
$added = array_diff($after, $before);
$removed = array_diff($before, $after);
}
and here is a test script:
<?php
$ar1 = array(
'one',
'two',
'three',
'four'
);
$ar2 = array(
'two',
'four',
'six',
'eight',
);
$adds = array();
$rems = array();
loadArrayDifferences($ar1, $ar2, $adds, $rems);
var_dump($adds);
var_dump($rems);
function loadArrayDifferences($before, $after, &$added, &$removed) {
$added = array_diff($after, $before);
$removed = array_diff($before, $after);
}
which outputs:
array(2) {
[2]=>
string(3) "six"
[3]=>
string(5) "eight"
}
array(2) {
[0]=>
string(3) "one"
[2]=>
string(5) "three"
}

Rebase array keys after unsetting elements [duplicate]

This question already has answers here:
How to re-index the values of an array in PHP? [duplicate]
(3 answers)
Closed 2 years ago.
I have an array:
$array = array(1,2,3,4,5);
If I were to dump the contents of the array they would look like this:
array(5) {
[0] => int(1)
[1] => int(2)
[2] => int(3)
[3] => int(4)
[4] => int(5)
}
When I loop through and unset certain keys, the index gets all jacked up.
foreach($array as $i => $info)
{
if($info == 1 || $info == 2)
{
unset($array[$i]);
}
}
Subsequently, if I did another dump now it would look like:
array(3) {
[2] => int(3)
[3] => int(4)
[4] => int(5)
}
Is there a proper way to reset the array so it's elements are Zero based again ??
array(3) {
[0] => int(3)
[1] => int(4)
[2] => int(5)
}
Try this:
$array = array_values($array);
Using array_values()
Got another interesting method:
$array = array('a', 'b', 'c', 'd');
unset($array[2]);
$array = array_merge($array);
Now the $array keys are reset.
Use array_splice rather than unset:
$array = array(1,2,3,4,5);
foreach($array as $i => $info)
{
if($info == 1 || $info == 2)
{
array_splice($array, $i, 1);
}
}
print_r($array);
Working sample here.
Just an additive.
I know this is old, but I wanted to add a solution I don't see that I came up with myself. Found this question while on hunt of a different solution and just figured, "Well, while I'm here."
First of all, Neal's answer is good and great to use after you run your loop, however, I'd prefer do all work at once. Of course, in my specific case I had to do more work than this simple example here, but the method still applies. I saw where a couple others suggested foreach loops, however, this still leaves you with after work due to the nature of the beast. Normally I suggest simpler things like foreach, however, in this case, it's best to remember good old fashioned for loop logic. Simply use i! To maintain appropriate index, just subtract from i after each removal of an Array item.
Here's my simple, working example:
$array = array(1,2,3,4,5);
for ($i = 0; $i < count($array); $i++) {
if($array[$i] == 1 || $array[$i] == 2) {
array_splice($array, $i, 1);
$i--;
}
}
Will output:
array(3) {
[0]=> int(3)
[1]=> int(4)
[2]=> int(5)
}
This can have many simple implementations. For example, my exact case required holding of latest item in array based on multidimensional values. I'll show you what I mean:
$files = array(
array(
'name' => 'example.zip',
'size' => '100000000',
'type' => 'application/x-zip-compressed',
'url' => '28188b90db990f5c5f75eb960a643b96/example.zip',
'deleteUrl' => 'server/php/?file=example.zip',
'deleteType' => 'DELETE'
),
array(
'name' => 'example.zip',
'size' => '10726556',
'type' => 'application/x-zip-compressed',
'url' => '28188b90db990f5c5f75eb960a643b96/example.zip',
'deleteUrl' => 'server/php/?file=example.zip',
'deleteType' => 'DELETE'
),
array(
'name' => 'example.zip',
'size' => '110726556',
'type' => 'application/x-zip-compressed',
'deleteUrl' => 'server/php/?file=example.zip',
'deleteType' => 'DELETE'
),
array(
'name' => 'example2.zip',
'size' => '12356556',
'type' => 'application/x-zip-compressed',
'url' => '28188b90db990f5c5f75eb960a643b96/example2.zip',
'deleteUrl' => 'server/php/?file=example2.zip',
'deleteType' => 'DELETE'
)
);
for ($i = 0; $i < count($files); $i++) {
if ($i > 0) {
if (is_array($files[$i-1])) {
if (!key_exists('name', array_diff($files[$i], $files[$i-1]))) {
if (!key_exists('url', $files[$i]) && key_exists('url', $files[$i-1])) $files[$i]['url'] = $files[$i-1]['url'];
$i--;
array_splice($files, $i, 1);
}
}
}
}
Will output:
array(1) {
[0]=> array(6) {
["name"]=> string(11) "example.zip"
["size"]=> string(9) "110726556"
["type"]=> string(28) "application/x-zip-compressed"
["deleteUrl"]=> string(28) "server/php/?file=example.zip"
["deleteType"]=> string(6) "DELETE"
["url"]=> string(44) "28188b90db990f5c5f75eb960a643b96/example.zip"
}
[1]=> array(6) {
["name"]=> string(11) "example2.zip"
["size"]=> string(9) "12356556"
["type"]=> string(28) "application/x-zip-compressed"
["deleteUrl"]=> string(28) "server/php/?file=example2.zip"
["deleteType"]=> string(6) "DELETE"
["url"]=> string(45) "28188b90db990f5c5f75eb960a643b96/example2.zip"
}
}
As you see, I manipulate $i before the splice as I'm seeking to remove the previous, rather than the present item.
I use $arr = array_merge($arr); to rebase an array. Simple and straightforward.
100% working for me ! After unset elements in array you can use this for re-indexing the array
$result=array_combine(range(1, count($your_array)), array_values($your_array));
Late answer but, after PHP 5.3 could be so;
$array = array(1, 2, 3, 4, 5);
$array = array_values(array_filter($array, function($v) {
return !($v == 1 || $v == 2);
}));
print_r($array);
Or you can make your own function that passes the array by reference.
function array_unset($unsets, &$array) {
foreach ($array as $key => $value) {
foreach ($unsets as $unset) {
if ($value == $unset) {
unset($array[$key]);
break;
}
}
}
$array = array_values($array);
}
So then all you have to do is...
$unsets = array(1,2);
array_unset($unsets, $array);
... and now your $array is without the values you placed in $unsets and the keys are reset
In my situation, I needed to retain unique keys with the array values, so I just used a second array:
$arr1 = array("alpha"=>"bravo","charlie"=>"delta","echo"=>"foxtrot");
unset($arr1);
$arr2 = array();
foreach($arr1 as $key=>$value) $arr2[$key] = $value;
$arr1 = $arr2
unset($arr2);

Categories