combining two arrays merge the same data add the new data - php

retrieve data from database :
$db = array (
0 =>
array (
'stay' => '10',
'end' => '2015-12-29',
'start' => '2015-12-20',
'pid' => '231096236',
'normal_price' => '385',
'promo_price' => '385',
'resell_price' => '385',
),
1 =>
array (
'stay' => '7',
'end' => '2016-01-05',
'start' => '2015-12-30',
'pid' => '231096235',
'normal_price' => '385',
'promo_price' => '385',
'resell_price' => '385',
),
2 =>
array (
'stay' => '3',
'end' => '2053-01-01',
'start' => '2016-01-06',
'pid' => '231096234',
'normal_price' => '385',
'promo_price' => '385',
'resell_price' => '385',
),
),
new array to merge with:
$new = array (
0 =>
array (
'stay' => '2',
'end' => '2015-07-01',
'start' => '2015-06-03',
'normal_price' => '145',
'promo_price' => '145',
'resell_price' => '135',
),
1 =>
array (
'stay' => '4',
'end' => '2015-07-05',
'start' => '2015-07-02',
'pid' => '231096235',
'normal_price' => '100',
'promo_price' => '100',
'resell_price' => '100',
),
2 =>
array (
'stay' => '4',
'end' => '2015-09-03',
'start' => '2015-07-06',
'pid' => '231096236',
'normal_price' => '100',
'promo_price' => '100',
'resell_price' => '100',
),
),
expected result:
$expected = array (
0 =>
array (
'stay' => '2',
'end' => '2015-07-01',
'start' => '2015-06-03',
'normal_price' => '145',
'promo_price' => '145',
'resell_price' => '135',
),
1 =>
array (
'stay' => '4',
'end' => '2015-07-05',
'start' => '2015-07-02',
'pid' => '231096235',
'normal_price' => '100',
'promo_price' => '100',
'resell_price' => '100',
),
2 =>
array (
'stay' => '4',
'end' => '2015-09-03',
'start' => '2015-07-06',
'pid' => '231096236',
'normal_price' => '100',
'promo_price' => '100',
'resell_price' => '100',
),
3 =>
array (
'stay' => '3',
'end' => '2053-01-01',
'start' => '2016-01-06',
'pid' => '231096234',
'normal_price' => '385',
'promo_price' => '385',
'resell_price' => '385',
),
),
my result so far:
$merge = array (
0 =>
array (
'stay' => '2',
'end' => '2015-07-01',
'start' => '2015-06-03',
'normal_price' => '145',
'promo_price' => '145',
'resell_price' => '135',
),
1 =>
array (
'stay' => '4',
'end' => '2015-07-05',
'start' => '2015-07-02',
'pid' => '231096235',
'normal_price' => '100',
'promo_price' => '100',
'resell_price' => '100',
),
2 =>
array (
'stay' => '4',
'end' => '2015-09-03',
'start' => '2015-07-06',
'pid' => '231096236',
'normal_price' => '100',
'promo_price' => '100',
'resell_price' => '100',
),
),
these are the requirements:
if record in new array does not has pid (price id) then it's
considered as new data. (record with start : 2015-06-03 and end :
2015-06-03)
if record in new array has pid and match with one of record from table, then new record's values will override the old one (record with pid : 231096235 and pid : 231096236)
if record from database has pid and does not match with any pid from new array then it should be added to new array (it shouldb record with pid : 231096234)
my functions :
$merge = array();
foreach ($new as $ikey => $ival) {
$ispid = (isset($ival['pid'])) ? (int) $ival['pid'] : 0;
if ($ispid === 0) {
$merge[] = $ival;
}
if ($ispid > 0) {
$exist = false;
foreach ($db as $rkey => $rval) {
$rspid = (int) $rval['pid'];
if ($ispid === $rspid) {
$spid_exist = true;
overridePriceValue($ival, $rval);
$merge[] = $rval;
}
}
// if ($exist === false) {
// echo "price id " . $ispid . " is not match with any special prices.";
// }
}
}
function overridePriceValue($input_spc_price, &$spc_price) {
if (isset($input_spc_price['stay'])) {
$spc_price['stay'] = $input_spc_price['stay'];
}
if (isset($input_spc_price['end'])) {
$spc_price['end'] = $input_spc_price['end'];
}
if (isset($input_spc_price['start'])) {
$spc_price['start'] = $input_spc_price['start'];
}
if (isset($input_spc_price['normal_price'])) {
$spc_price['normal_price'] = $input_spc_price['normal_price'];
}
if (isset($input_spc_price['promo_price'])) {
$spc_price['promo_price'] = $input_spc_price['promo_price'];
}
if (isset($input_spc_price['resell_price'])) {
$spc_price['resell_price'] = $input_spc_price['resell_price'];
}
}
I need your advise to achieve the goal. thanks :)

You can use the UDF in_array_r from another stackoverflow question (thanks to jwueller) and do it like this:
$merge = $new;
foreach($db as $item) {
if (!in_array_r($item["pid"], $new)) {
$merge[] = $item;
}
}
function in_array_r($needle, $haystack, $strict = false) {
foreach ($haystack as $item) {
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict))) {
return true;
}
}
return false;
}

Related

iterate over 2 arrays in PHP to display items with same account id

I have two classes containing informations about accounts and invoices like this
The accounts list
array (
0 =>
'id' => 1,
'username' => 'abc',
'company' => 'My Corporation',
)),
1 =>
'id' => 2,
'username' => 'cde',
'company' => 'My Company',
))
The invoice list
array (
0 =>
'account_id' => 1,
'invoiceId' => '15',
)),
1 =>
'id' => 2,
'account_id' => '2',
'invoiceId' => '17',
)),
2 =>
'account_id' => 1,
'invoiceId' => '20',
)),
3 =>
'id' => 2,
'account_id' => '2',
'invoiceId' => '30',
))
When iterating over both collections each invoice to be shown once. My issues is that everything will be duplicated
My code is
<?php
foreach ($invoices as $invoice) {
foreach($accounts as $account) {
echo $account->getUsername($invoice->getAccountId())."<BR>";
echo $account->getCompany($invoice->getAccountId());
}
}
I am not sure what I should do
I think this sould solve tour problem:
<?php
$accounts = array (
0 => array (
'id' => 1,
'username' => 'abc',
'company' => 'My Corporation',
),
1 => array (
'id' => 2,
'username' => 'cde',
'company' => 'My Company',
));
$invoices = array (
0 => array (
'account_id' => 1,
'invoiceId' => '15',
),
1 => array (
'id' => 2,
'account_id' => '2',
'invoiceId' => '17',
),
2 => array (
'account_id' => 1,
'invoiceId' => '20',
),
3 => array (
'id' => 2,
'account_id' => '2',
'invoiceId' => '30',
));
foreach($accounts as $account) {
foreach ($invoices as $invoice) {
echo "account id : ";
echo $account['id'];
echo "invoices: ";
if ( $invoice['account_id'] === $account['id'] ) {
echo $invoice['account_id'];
// echo $account->getUsername($invoice->getAccountId())."<BR>";
// echo $account->getCompany($invoice->getAccountId());
}
}
}

Loop Through Nested JSON Response PHP

I'm trying to loop through and return data ('rank' from 'rank_details') from a returned JSON response.
Here is a snippet of the JSON response (what I'm getting from: $array = json_decode($apiResponse); )
(object) array(
'obj' =>
array (
0 =>
(object) array(
'name' => 'I\'m a HellRazor (feat. Crucifix)',
'id' => 13859011,
'data' =>
array (
0 =>
(object) array(
'timestp' => '2019-10-27T00:00:00.000Z',
'score' => 1.9610844011276853,
'rank_details' =>
array (
0 =>
(object) array(
'rank' => 191,
'country' => 'RU',
'score' => 1.9610844011276853,
'genre' => 'Country',
),
),
),
1 =>
(object) array(
'timestp' => '2019-12-04T00:00:00.000Z',
'score' => 14.70808550760029,
'rank_details' =>
array (
0 =>
(object) array(
'rank' => 9,
'country' => 'CH',
'score' => 14.70808550760029,
'genre' => 'Country',
),
),
),
2 =>
(object) array(
'timestp' => '2020-03-18T00:00:00.000Z',
'score' => 13.299189761918104,
'rank_details' =>
array (
0 =>
(object) array(
'rank' => 5,
'country' => 'RU',
'score' => 13.299189761918104,
'genre' => 'Country',
),
),
),
3 =>
(object) array(
'timestp' => '2020-07-12T00:00:00.000Z',
'score' => 19.02841337415393,
'rank_details' =>
array (
0 =>
(object) array(
'rank' => 77,
'country' => 'DE',
'score' => 19.02841337415393,
'genre' => 'Country',
),
),
),
4 =>
(object) array(
'timestp' => '2020-10-02T00:00:00.000Z',
'score' => 2.631257456412845,
'rank_details' =>
array (
0 =>
(object) array(
'rank' => 154,
'country' => 'RU',
'score' => 2.631257456412845,
'genre' => 'Country',
),
),
),
5 =>
(object) array(
'timestp' => '2020-10-03T00:00:00.000Z',
'score' => 1.896575572629275,
'rank_details' =>
array (
0 =>
(object) array(
'rank' => 195,
'country' => 'RU',
'score' => 1.896575572629275,
'genre' => 'Country',
),
),
),
),
),.....
Here is a snippet of my code:
$apiResponse = curl_exec($cc);
$array = json_decode($apiResponse);
foreach ($array as $key => $arrays) { // This will search in the 2 jsons
foreach($arrays as $key => $value) {
echo "\n Record ID: " . $value->id;
echo "\n Record Name: " . $value->name;
echo "\n Record Rank: " . $value->obj->data->rank_details->rank;
echo "\n";
}
}
Record Name and ID come over fine, but anything not in the "top level" isn't coming over. Any help is GREATLY appreciated.
You have to index into the data and rank_details arrays even if there's only one entry.
This worked for me:
echo "\n Record Rank: " . $value->data[0]->rank_details[0]->rank;

Getting largest values from different arrays

I want to get the largest values from different arrays. Basically, the arrays are populated from 3 different websites, and I need to know what are the largest tags and photos values of each product.
I have the following array:
$data = array(
'domain1.com' => array(
'id1' => array(
'tags' => '5',
'photos' => '4',
),
'id2' => array(
'tags' => '8',
'photos' => '2',
),
'id3' => array(
'tags' => '6',
'photos' => '1',
),
),
'domain2.com' => array(
'id1' => array(
'tags' => '3',
'photos' => '1',
),
'id2' => array(
'tags' => '4',
'photos' => '9',
),
'id3' => array(
'tags' => '2',
'photos' => '0',
),
),
'domain3.com' => array(
'id1' => array(
'tags' => '7',
'photos' => '3',
),
'id2' => array(
'tags' => '9',
'photos' => '5',
),
'id3' => array(
'tags' => '2',
'photos' => '4',
),
),
);
I need to get the following result:
$data = array(
'id1' => array(
'tags' => '7',
'photos' => '4',
),
'id2' => array(
'tags' => '9',
'photos' => '9',
),
'id3' => array(
'tags' => '6',
'photos' => '4',
),
);
This is solveable with a simple loop:
$new = array();
foreach($data as $domain){
foreach($domain as $id => $_data){
foreach($_data as $elem => $value) {
if(!isset($new[$id][$elem]) || $value > $new[$id][$elem]){
$new[$id][$elem] = $value;
}
}
}
}
Which returns:
Array
(
[id1] => Array
(
[tags] => 7
[photos] => 4
)
[id2] => Array
(
[tags] => 9
[photos] => 9
)
[id3] => Array
(
[tags] => 6
[photos] => 4
)
)
Example
The easiest way is to use nested foreach loops to iterate and capture the data. The results are updated if there is a higher value found in the results array.
$results = [];
foreach ($data as $domain => $items) {
foreach ($items as $id => $elements) {
if (!isset($results[ $id ])) {
$results[ $id ] = [];
}
foreach ($elements as $tag => $value) {
if (!isset($results[ $id ][ $tag ]) || $value>$results[ $id ][ $tag ]) {
$results[ $id ][ $tag ] = $value;
}
}
}
}
print_r($results);

Extracting data from complicated associative array in php and put into new array

I have an complicated array that looks like this:
$input=array(
(int) 0 => array(
'XXX' => array(
'id' => '7',
'p_id' => '1',
'address' => '9463',
'arrival_time' => '2014-05-01 03:30:00'
),
'YYY' => array(
'id' => '1',
'iden' => '1111',
'name' => 'Tom'
)
),
(int) 1 => array(
'XXX' => array(
'id' => '9',
'p_id' => '2',
'address' => '9469',
'arrival_time' => '2014-05-27 16:43:58'
),
'YYY' => array(
'id' => '2',
'iden' => '2222',
'name' => 'Sam'
)
),
(int) 2 => array(
'XXX' => array(
'id' => '3',
'p_id' => '3',
'address' => '9462',
'arrival_time' => '2014-04-21 14:05:00'
),
'YYY' => array(
'id' => '3',
'iden' => '3333',
'name' => 'James'
)
)
)
I would like to convert it such that it looks like this;
$output=array(
(int) 0 => array(
'name' => 'Tom',
'iden' => '1111',
'address' => '9463'
),
(int) 1 => array(
'name' => 'Sam',
'iden' => '2222',
'address' => '9469'
),
(int) 2 => array(
'name' => 'James',
'iden' => '3333',
'address' => '9462'
)
I wrote some code to solve this problem:
foreach ( $input as $key => $value)
{
$output['name']=$input[$key]['YYY']['name'];
$output['iden']=$input[$key]['YYY']['iden'];
$output['address']=$input[$key]['XXX']['address'];
}
Unfortunately, it retrieves only the last element of the input array.
Can someone more experienced help?
Thank you very much.
You are overwriting the values in each iteration, as you always write to $output['name'] etc.
foreach ( $input as $key => $value)
{
$output[$key] = array(
'name' => $value['YYY']['name'],
'iden' => $value['YYY']['iden'],
'address' => $value['XXX']['address']
);
}
The key here is using $output[$key] instead of $output - this way you will add a new element in each iteration.
Also $input[$key] and $value are equivalent, so I used the shorter variant ;)
Try this in your foreach loop :-
foreach ( $input as $key=>$value)
{
$output[$key]['name']=$value['YYY']['name'];
$output[$key]['iden']=$value['YYY']['iden'];
$output[$key]['address']=$value['XXX']['address'];
}
You have to add an index to the array in the foreach: $output[$key]["name"] = ...;

how to build an array in parent and child manner by fetching mysql data using php

this is my code where i am fetching my mysql record.
$parentChildArr=array();
//mysql query for fetching parent and child record
$selectparentMenu=mysql_query("SELECT `id`,`item_name`,`menu_type`,`parent` FROM `epic_master_menu`");
if(mysql_num_rows($selectparentMenu)>1) {
while($fetchparentMenu=mysql_fetch_array($selectparentMenu)) {
$parentChildArr[]=$fetchparentMenu['id'];
$parentChildArr[]=$fetchparentMenu['item_name'];
$parentChildArr[]=$fetchparentMenu['menu_type'];
$parentChildArr[]=$fetchparentMenu['parent'];
}
var_export($parentChildArr); // exporting or printing arrays
// when i export the array i get this output.
array ( 0 => '1', 1 => 'Dashboard', 2 => 'item', 3 => '0',
4 => '2', 5 => 'Admission', 6 => 'item', 7 => '0', 8 => '3',
9 => 'Examination', 10 => 'item', 11 => '0', 12 => '4',
13 => 'CET', 14 => 'item', 15 => '0');
but the problem is that i want to build the array like this.
$newarr=array ( 'dataSource' => array ( 0 => array ( 'id' => '1',
'text' => 'Dashboard', 'expanded' => 'true', 'spriteCssClass' => 'rootfolder',
'items' => array ( 0 => array ( 'id' => '89', 'text' => 'Users',
'expanded' => true, 'spriteCssClass' => 'folder',
'items' => array ( 0 => array ( 'id' => '94', 'text' => 'Users',
'spriteCssClass' => 'html', ), 1 => array ( 'id' => '94',
'text' => 'Users', 'spriteCssClass' => 'html', ), 2 => array (
'id' => '94', 'text' => 'Users', 'spriteCssClass' => 'image' ) ) ) ) ) ));
database table view is...
i am not getting the logic that how to build the array like $newarr. thank you
not tested, but you need to defined a structure and then you need to go recursive... so you can check where is the parent entry to my child ...
function structure($data){
return array(
'id' => $data['id'],
'item_name' => $data['item_name'],
'menu_type' => $data['menu_type'],
'parent' => $data['parent'],
'expanded' => false,
'childs' => array()
);
}
function recursiveImport(&$parent, $data){
foreach($parent AS $key => $value){
if($value['id'] == $data['parent']){
$parent[$key]['childs'][] = structure($data);
$parent[$key]['expanded'] = true;
return true;
}
else{
if(count($value['childs']) > 0){
foreach($value['childs'] AS $key2 => $child){
$result = recursiveImport($parent[$key]['childs'][$key2], $data);
if($result === true) return true;
}
}
}
}
return false;
}
$newarr = array();
while($fetchparentMenu=mysql_fetch_array($selectparentMenu)) {
$result = recursiveImport($newarr , $fetchparentMenu);
if($result === false){
$newarr[] = structure($fetchparentMenu);
}
}
//output array
array ( 0 => array ( 'id' => '1', 'item_name' => 'Dashboard', 'menu_type' => 'item', 'parent' => '0', 'expanded' => false, 'childs' => array ( ), ), 1 => array ( 'id' => '2', 'item_name' => 'Admission', 'menu_type' => 'item', 'parent' => '0', 'expanded' => false, 'childs' => array ( ), ), 2 => array ( 'id' => '3', 'item_name' => 'Examination', 'menu_type' => 'item', 'parent' => '0', 'expanded' => false, 'childs' => array ( ), ), 3 => array ( 'id' => '4', 'item_name' => 'CET', 'menu_type' => 'item', 'parent' => '0', 'expanded' => false, 'childs' => array ( ), )
Use following code
$m=0;
if(mysql_num_rows($selectparentMenu)>1) {
while($fetchparentMenu=mysql_fetch_array($selectparentMenu)) {
$parentChildArr[$m][]=$fetchparentMenu['id'];
$parentChildArr[$m][]=$fetchparentMenu['item_name'];
$parentChildArr[$m][]=$fetchparentMenu['menu_type'];
$parentChildArr[$m][]=$fetchparentMenu['parent'];
$m++;
}

Categories