Global array in php issues - php

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);

Related

How to sort a multidimensional class in php with different subarray name

Can someone help me about my problem... I have a php multidimensional array and i need to sort it by "PRICE" with PHP... I tried to use sort() but it don't work because every main array have a different currency name..
Here is an example of my array :
array(3) {
["MLN"]=>
array(1) {
["EUR"]=>
array(23) {
["FROMSYMBOL"]=>
string(3) "MLN"
["TOSYMBOL"]=>
string(3) "EUR"
["PRICE"]=>
float(0.01699)
}
}
["BTC"]=>
array(1) {
["EUR"]=>
array(23) {
["FROMSYMBOL"]=>
string(3) "BTC"
["TOSYMBOL"]=>
string(3) "EUR"
["PRICE"]=>
int(8769)
}
}
["LTC"]=>
array(1) {
["EUR"]=>
array(23) {
["FROMSYMBOL"]=>
string(3) "LTC"
["TOSYMBOL"]=>
string(3) "EUR"
["PRICE"]=>
float(141.47)
}
}
}
Is someone who have an idea to sort my currencies by PRICE?
Thanks a lot
You could use uasort():
uasort($array, function($a, $b) {
return $a['EUR']['PRICE'] - $b['EUR']['PRICE'];
});
I'm using an anonymous function in this example but you could also define the comparison function separately.
You could try something like this :
$sorted = [] ;
foreach ($array as $key => $item) {
$price = reset($item)['PRICE'] ;
$sorted[$price] = [$key => $item] ;
}
krsort($sorted);
$array = [];
foreach ($sorted as $sort) {
$keys = array_keys($sort) ;
$array[reset($keys)] = reset($sort) ;
}
unset($sorted);
print_r($array);
Will keep keys and sort array.
Output :
Array
(
[BTC] => Array
(
[EUR] => Array
(
[FROMSYMBOL] => BTC
[TOSYMBOL] => EUR
[PRICE] => 8769
)
)
[LTC] => Array
(
[EUR] => Array
(
[FROMSYMBOL] => LTC
[TOSYMBOL] => EUR
[PRICE] => 141.47
)
)
[MLN] => Array
(
[EUR] => Array
(
[FROMSYMBOL] => MLN
[TOSYMBOL] => EUR
[PRICE] => 0.01699
)
)
)
If you want a somewhat messy object oriented approach, I've made a class that is supposed to order an array of classes based on a shared property:
https://gist.github.com/kyrrr/b208693a59f184fe607660e0dfa8631d
A class that represents your data (quick and dirty):
class Exchange{
public $currencyName;
public $toSymbol;
public $rate;
function __construct($name, $to, $rate)
{
$this->currencyName = $name;
$this->toSymbol = $to;
$this->rate = $rate;
}
}
Then you can do:
$orderer = new PropertyOrderHelper();
$foo = new Exchange("MLN", "EUR", 0.0169);
$bar = new Exchange("BTC", "EUR", 20);
$exchanges = [$foo, $bar];
var_dump($orderer->orderBy($exchanges, "rate"));
var_dump($orderer->orderBy($exchanges, "rate", 'desc'));

How to merge subarrays using keys and sum the values?

I'm fairly new to PHP and I'm having some trouble with arrays and combining data. I have the following array which has been created from a foreach loop:
array(1) {
[36868]=> int(3)
}
array(1) {
[2112]=> int(3)
}
array(1) {
[35901]=> int(3)
}
array(1) {
[6496]=> int(3)
}
array(1) {
[87]=> int(3)
}
array(1) {
[36868]=> int(3)
}
array(1) {
[68]=> int(3)
}
array(1) {
[9068]=> int(3)
}
array(1) {
[47]=> int(3)
}
The key in each array is a user ID, so I need to preserve this, but I only want one instance of each key and where there are duplicate keys, sum the values. Like so:
array(1) {
[36868]=> int(6)
}
array(1) {
[2112]=> int(3)
}
array(1) {
[35901]=> int(3)
}
array(1) {
[6496]=> int(3)
}
array(1) {
[87]=> int(3)
}
array(1) {
[68]=> int(3)
}
array(1) {
[9068]=> int(3)
}
array(1) {
[47]=> int(3)
}
The I've tried looping through the array:
foreach ($array as $key => &$value) {
if ($value[0] == $value[1]) {
$value[1] += $value[1];
}
}
But with no luck. I've also tried rendering the arrays differently i.e. [userid]=>1,[score]=>3 and I feel like I'm going round in circles a bit, so any help would be hugely appreciated.
$data <-- this is your original array
$result = array_reduce(
$data,
function($carry, $item) {
foreach ($item as $id => $score) {
if (array_key_exists($id, $carry)) {
$carry[$id] += $score;
} else {
$carry[$id] = $score;
}
}
return $carry;
},
[]
);
If you are sure that each item only contains 1 entry you could also simplify the callback to not use foreach:
$result = array_reduce(
$data,
function ($carry, $item) {
$score = reset($item);
$id = key($item);
if (array_key_exists($id, $carry)) {
$carry[$id] += $score;
} else {
$carry[$id] = $score;
}
return $carry;
},
[]
);
You could also keep using foreach instead:
/** foreach to create a $data array like described below and afterwards do this: **/
$result = [];
foreach($data as $row) {
$score = reset($row);
$id = key($row);
if (array_key_exists($id, $result)) {
$result[$id] += $score;
} else {
$result[$id] = $score;
}
}
This will take an array $data like this:
array(
array('1' => 3),
array('1' => 3),
array('2' => 3),
);
and creates the variable $result like this:
array(
'1' => 6,
'2' => 3,
);
Here is a clean method that will not produce Notices. When merge-summing array data the efficient method is to generate temporary keys and use the very fast isset() function. I could have used current() and key() to access the lone subarray element, but the second foreach control structure is actually faster and more compact. (Ref:
https://stackoverflow.com/a/21219594/2943403 )
Code: (Demo)
$array = [
[36868 => 3],
[2112 => 3],
[35901 => 3],
[6496 => 3],
[87 => 3],
[36868 => 3],
[68 => 3],
[9068 => 3],
[47 => 3]
];
$result = [];
foreach ($array as $subarray) {
foreach ($subarray as $k => $v) {
if (!isset($result[$k])) {
$result[$k] = $subarray;
} else {
$result[$k][$k] += $v;
}
}
}
var_export(array_values($result));
Output:
array (
0 =>
array (
36868 => 6,
),
1 =>
array (
2112 => 3,
),
2 =>
array (
35901 => 3,
),
3 =>
array (
6496 => 3,
),
4 =>
array (
87 => 3,
),
5 =>
array (
68 => 3,
),
6 =>
array (
9068 => 3,
),
7 =>
array (
47 => 3,
),
)

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));

PHP add counter to name if already exists in array

I have the following multi-dimensional array and I need to iterate over it and wherever there is a duplicate name, a counter is added to the name.
[1] => Array
(
[0] => Array
(
[clientName] => John Smith
[clientType] => 0
[clientDOB] => 1980-10-14
)
)
[2] => Array
(
[0] => Array
(
[clientName] => John Smith
[clientType] => 0
[clientDOB] => 1970-01-01
)
[1] => Array
(
[clientName] => Jeremy White
[clientType] => 2
[clientDOB] => 2015-08-19
)
)
The code I'm using is this :
$finalNames = array_map(function ($item) use (&$namesCount) {
if (!isset($namesCount[$item['clientName']])) {
$namesCount[$item['clientName']] = 0;
}
$namesCount[$item['clientName']]++;
$item['clientName'] = $item['clientName'] . ' ' . $namesCount[$item['clientName']];
return $item;
}, $arrayOfTravellers);
array_map(function($item, $key) use ($namesCount, &$finalNames) {
$finalNames[$key]['clientName'] = $namesCount[$item['clientName']] == 1
? str_replace(' 1', '', $finalNames[$key]['clientName'])
: $finalNames[$key]['clientName'];
}, $arrayOfNames, array_keys($arrayOfTravellers));
Which is returning a bunch of errors such as :
Notice: Undefined index: clientName in /Applications/MAMP/htdocs/europatours/functions/reportsFunctions.php on line 330
My assumption is that the code is not fit for a multi-dimensional array. Can anyone help please? I need to retain the complete structure of the array only where there is a duplicate name, a counter is added such as John Smith 1, John Smith 2 whereas Jeremy White remains without a counter.
$arrayOfNames = array(
array('clientName' => 'John'),
array('clientName' => 'John'),
array('clientName' => 'Mary'),
array('clientName' => 'Mary'),
array('clientName' => 'Mary'),
array('clientName' => 'Tony'),
array('clientName' => 'Alex')
);
$namesCount = array();
$finalNames = array_map(function ($item) use (&$namesCount) {
if (!isset($namesCount[$item['clientName']])) {
$namesCount[$item['clientName']] = 0;
}
$namesCount[$item['clientName']]++;
$item['clientName'] = $item['clientName'] . ' ' . $namesCount[$item['clientName']];
return $item;
}, $arrayOfNames);
array_map(function($item, $key) use ($namesCount, &$finalNames) {
$finalNames[$key]['clientName'] = $namesCount[$item['clientName']] == 1
? str_replace(' 1', '', $finalNames[$key]['clientName'])
: $finalNames[$key]['clientName'];
}, $arrayOfNames, array_keys($arrayOfNames));
echo '<pre>';
var_dump($finalNames);
echo '</pre>';
The output would be:
array(7) {
[0]=>
array(1) {
["clientName"]=>
string(6) "John 1"
}
[1]=>
array(1) {
["clientName"]=>
string(6) "John 2"
}
[2]=>
array(1) {
["clientName"]=>
string(6) "Mary 1"
}
[3]=>
array(1) {
["clientName"]=>
string(6) "Mary 2"
}
[4]=>
array(1) {
["clientName"]=>
string(6) "Mary 3"
}
[5]=>
array(1) {
["clientName"]=>
string(4) "Tony"
}
[6]=>
array(1) {
["clientName"]=>
string(4) "Alex"
}
}
What about a combination of array_column and in_array when adding new values?
$records = array(); // your data
$name = 'John';
$i = 0;
do
{
$newName = $name . ( ($i == 0)? '' : ' '.$i );
$i++;
}
while (in_array($newName, array_column($records, 'clientName')));
$records[] = array('clientName' => $newName);
Due to performance issues you may want to call array_columns only once before the loop and store the results in a variable.

Merging arrays 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);

Categories