I have this array structure:
array (
0 =>
array (
'id' => '17',
'name' => 'aba aba',
'english_name' => 'ABA ABA',
'group_id' => '1',
),
1 =>
array (
'id' => '23',
'name' => 'bcb bcb',
'english_name' => 'BCB BCB',
'group_id' => '2',
),
2 =>
array (
'id' => '17',
'name' => 'aba aba',
'english_name' => 'ABA ABA',
'group_id' => '4',
),
);
I want to create another array with no duplicates but having in mind in which group_id are the duplicate ones. I'm looking for this structure:
array (
17 =>
array (
'name' => 'ABA ABA',
'groups' =>
array (
0 => '1',
1 => '4',
),
),
23 =>
array (
'name' => 'BCB BCB',
'groups' =>
array (
0 => '2',
),
),
);
I tried with this code but it doesn't give me what I'm looking for, I don't know what I'm doing wrong.
Code:
foreach ($array as $value) {
if (!in_array($value['id'], $array[$value['id']] )) {
$interested [$value['id']]['name'] = $value['english_name'];
$interested [$value['id']]['groups'][]= $value['group_id'];
} else if (in_array($value['id'], $array[$value['id']] )){
$interested [$value['id']]['groups'][] = $value['group_id'];
}
}
Simple loop and assign using the id as your pivot:
<?php
$data =
array (
0 =>
array (
'id' => '17',
'name' => 'aba aba',
'english_name' => 'ABA ABA',
'group_id' => '1',
),
1 =>
array (
'id' => '23',
'name' => 'bcb bcb',
'english_name' => 'BCB BCB',
'group_id' => '2',
),
2 =>
array (
'id' => '17',
'name' => 'aba aba',
'english_name' => 'ABA ABA',
'group_id' => '4',
),
);
foreach($data as $item) {
$result[$item['id']]['name'] = $item['english_name'];
$result[$item['id']]['groups'][] = $item['group_id'];
}
var_export($result);
Output:
array (
17 =>
array (
'name' => 'ABA ABA',
'groups' =>
array (
0 => '1',
1 => '4',
),
),
23 =>
array (
'name' => 'BCB BCB',
'groups' =>
array (
0 => '2',
),
),
)
$data = array (
0 =>
array (
'id' => '17',
'name' => 'aba aba',
'english_name' => 'ABA ABA',
'group_id' => '1',
),
1 =>
array (
'id' => '23',
'name' => 'bcb bcb',
'english_name' => 'BCB BCB',
'group_id' => '2',
),
2 =>
array (
'id' => '17',
'name' => 'aba aba',
'english_name' => 'ABA ABA',
'group_id' => '4',
),
);
function unique_multidim_array($array, $key) {
$temp_array = array();
$i = 0;
$key_array = array();
foreach($array as $val) {
if (!in_array($val[$key], $key_array)) {
$key_array[$i] = $val[$key];
$temp_array[$i] = $val;
}
$i++;
}
return $temp_array;
}
$newdata = unique_multidim_array($data,'id');
The function taken from here. Details on : https://www.php.net/manual/tr/function.array-unique.php
It isn't very clear from your code what you are trying to do, but below is one way.
Loop over your subarrays one by one.
have a new array, say $set which will be an associative array of keys and values where keys are the IDs and values are the name and groups attributes.
If $set has the ID isset already, add to groups, else, create a new one and then add groups.
Snippet:
<?php
$set = [];
foreach($array as $val){
$group_id = $val['group_id'];
if(!isset($set[$val['id']])){
$set[$val['id']] = [
'name' => $val['english_name'],
'groups' => []
];
}
$set[$val['id']]['groups'][] = $group_id;
}
print_r($set);
Demo: http://sandbox.onlinephpfunctions.com/code/af65effc35a0275bdf6908c77dc0cb701d36010e
Functional way)
function group( $groups, $item ) {
$id = $item['id'];
if ( !isset($groups[$id]) ) {
$groups[$id] = array (
'name' => $item['name'],
'groups' => array(),
);
}
array_push($groups[$id]['groups'], $item['group_id']);
return $groups;
}
array_reduce($data, 'group', array());
Please take a look at playground
Also to make groups array unique PHP Collections could be used. For example, Set data structure.
Related
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());
}
}
}
Thank you in advance. Is there any way to create a multidimensional array from key names.
$array = array(
'brand/name' => 'BRAND_NAME',
'brand/model' => 'MODEL_NO',
'brand/inv/qty' => '20',
'brand/inv/cost' => '30',
'wh' => 'NY',
'brand/inv/sales' => '40'
);
Transform to this array.
$array = array(
'brand' => array(
'name' => 'BRAND_NAME',
'model' => 'MODEL_NO',
'inv' => array(
'qty' => 20,
'cost' => 30,
'sales' => 40,
)
),
'wh' => 'NY'
);
Thank you !
Try my code (I used the reference operator "&" to get the successive inner arrays):
Input array:
$array = array(
'brand/name' => 'BRAND_NAME',
'brand/model' => 'MODEL_NO',
'brand/inv/qty' => '20',
'brand/inv/cost' => '30',
'wh' => 'NY',
'brand/inv/sales' => '40'
);
php code:
<?php
$resultArray = array();
foreach($array as $path => $element) {
$pathArray = explode("/", $path);
$auxRef = &$resultArray;
foreach($pathArray as $pathPart) {
if(! array_key_exists($pathPart, $auxRef)) {
$auxRef[$pathPart] = array();
}
$auxRef = &$auxRef[$pathPart];
}
$auxRef = $element;
unset($auxRef);
}
?>
Result array:
array ( 'brand' => array ( 'name' => 'BRAND_NAME', 'model' => 'MODEL_NO', 'inv' => array ( 'qty' => '20', 'cost' => '30', 'sales' => '40', ), ), 'wh' => 'NY', )
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;
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);
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"] = ...;