I currently have an array, created from a database, an example of which looks like the following:
Array(
[0] => Array (
objectid => 2,
name => title,
value => apple
),
[1] => Array (
objectid => 2,
name => colour,
value => red
),
[2] => Array (
objectid => 3,
name => title,
value => pear
),
[3] => Array (
objectid => 3,
name => colour,
value => green
)
)
What I would like to do is group all the items in the array by their objectid, and convert the 'name' values into keys and 'value' values into values of an associative array....like below:
Array (
[0] => Array (
objectid => 2,
title => apple,
colour => red
),
[1] => Array (
objectid => 3,
title => pear,
colour => green
)
)
I've tried a few things but haven't really got anywhere.. Any ideas?
Thanks in advance
This should work with your current setup and should be able to handle as many key-value pairs as available:
<?php
$results = array(
array('objectid' => 2, 'name' => 'title', 'value' => 'apple'),
array('objectid' => 2, 'name' => 'color', 'value' => 'red'),
array('objectid' => 3, 'name' => 'title', 'value' => 'pear'),
array('objectid' => 3, 'name' => 'color', 'value' => 'green'));
$final = array();
foreach ($results as $result) {
$final[$result['objectid']]['objectid'] = $result['objectid'];
$final[$result['objectid']][$result['name']] = $result['value'];
}
print_r($final);
It would be easier to have the array keys correspond with your object id, that way you can iterate through your existing array, and add the key-value pairs for each object, like so:
$newArray = array();
foreach ($results as $result) {
if (!array_key_exists($result['objectid'], $newArray)) {
$newArray[$result['objectid'] = array();
}
foreach ($result as $key => $value) {
$newArray[$result['objectid'][$key] = $value;
}
}
Peter's method is perfectly valid, I just thought I would show a shorter version of the same thing (couldn't do in a comment)
foreach( $array as $obj ) {
if( !isset( $objects[$obj['objectid']] ) )
$objects[$obj['objectid']]['objectid'] = $obj['objectid'];
$objects[$obj['objectid']][$obj['name']] = $obj['value'];
}
Related
I got the follwing array and I would like to retrieve the name by the id:
Array
(
[0] => Array
(
[id] => 1
[name] => john
)
[1] => Array
(
[id] => 2
[name] => mark
)
etc...
It is doable with double foreach loop and a conditional test, but is there a more elegant way?
Assuming that id is unique...
Long Version
$arr = [
['id'=1, 'name'='john'],
['id'=2, 'name'='mark'],
];
$lookup = [];
foreach($arr as $row) {
$id = $row['id'];
$name = $row['name'];
$lookup[$id] = $name;
}
// find name for id, 2
echo $lookup[2];
// ==> mark
Short Version
...see Progrock’s solution!
You can use array_column to map ids to names:
<?php
$arr = [
['id' => 1, 'name' => 'Rolf'],
['id' => 3, 'name' => 'Gary'],
['id' => 2, 'name' => 'Jimmy'],
];
$id_names = array_column($arr, 'name', 'id');
var_export($id_names);
print $id_names[3];
Output:
array (
1 => 'Rolf',
3 => 'Gary',
2 => 'Jimmy',
)Gary
I try like this :
<?php
$list_team = array(
(object)array(
'id' => 1,
'name' => 'chelsea.jpg'
),
(object)array(
'id' => 2,
'name' => 'mu.jpg'
),
(object)array(
'id' => 3,
'name' => 'arsenal.jpg'
),
);
$team = 'chelsea.jpg';
echo '<pre>';print_r($team);echo '</pre>';
echo '<pre>';print_r($list_team);echo '</pre>';
foreach($list_team as $key => $value) {
if($value->name == $team)
$team_selected = $team;
}
echo '<pre>';print_r($team_selected);echo '</pre>';
die();
?>
If the code executed, the result like this :
chelsea.jpg
Array
(
[0] => stdClass Object ( [id] => 1
[name] => chelsea.jpg
)
[1] => stdClass Object
(
[id] => 2
[name] => mu.jpg
)
[2] => stdClass Object
(
[id] => 3
[name] => arsenal.jpg
)
)
chelsea.jpg
The code using loop
But, I do not want to use a loop
How can I do it?
Try the following:
$key = array_search($team, array_column($list_team, 'name'));
$team_selected = $list_team[$key]->name;
This will search array with name and return the and return the key of the main array and you can use that to access the contents of the nested array and assign the value to. $team_selected
Using array_search(), and array_column()
<?php
$list_team = array(
(object)array(
'id' => 1,
'name' => 'chelsea.jpg'
),
(object)array(
'id' => 2,
'name' => 'mu.jpg'
),
(object)array(
'id' => 3,
'name' => 'arsenal.jpg'
),
);
$team = 'chelsea.jpg';
// array column, returns all value of sub array, with key name
// array_search will return key
$key = array_search($team, array_column($list_team, 'name'));
if($key!==false){
// your object will be
print_r($list_team[$key]);
// access remaining..
echo $list_team[$key]->name.' '. $list_team[$key]->id.PHP_EOL;
}
?>
If you want to access specific attributes in multidimensional arrays, you can do the following thing.
For example, return the ID of the first array:
echo $list_team[0]["id"];
Simply change the [0] to [1] or whatever to mention the array you wanna call, and then simply use the attribute. But if you wanna print the whole array, I really recommend you to stay on loops. With loops you're sure you get all elements. Lets say you hardcode it like I said and then a month later you add 10 new arrays, so you'll have to edit your whole code.
I would like to merge the associative elements from my second array into my first array where the second array's subarray key matches a row's epg_channel_id value.
First array:
[
[
'num' => 1,
'name' => 'name 1',
'epg_channel_id' => 'ch111',
'added' => '1505435915',
],
[
'num' => 2,
'name' => 'name 2',
'epg_channel_id' => 'ch222',
'added' => '1505435915',
],
[
'num' => 3,
'name' => 'name 3',
'epg_channel_id' => 'ch333',
'added' => '1505435915',
],
[
'num' => 4,
'name' => 'name 4',
'epg_channel_id' => 'ch444',
'added' => '1505435915'
]
]
And the second array:
[
['ch000' => 'Um9jayBJbiBSaW8='],
['ch111' => 'Um9jayBJbiBSaW8='],
['ch222' => 'Um9jayBJbiBSaW8='],
['ch333' => 'Um9jayBJbiBSaW8='],
['ch444' => 'Um9jayBJbiBSaW8=']
]
Desired output (for one row):
Array
(
[0] => Array
(
[num] => 1
[name] => name 1
[epg_channel_id] => ch111
[added] => 1505435915
[ch111] => Um9jayBJbiBSaW8=
)
...
)
I tried array_recursive, array merge and not works.
If the corresponding indexes in both arrays are guaranteed to have the same channel id, this will work quite efficiently. For example, if $array1[0] is guaranteed to have the same channel id as $array2[0] this solution will work nicely:
$combined = [];
foreach($array1 as $key=>$val){
$combined[$key] = $val + $array2[$key];
}
However, if the corresponding indexes are not guaranteed to have the same channel ids, this solution will not work, and you'll need to use one of the other posted answers.
One last note if you do use this method is that if the arrays are different sizes, you will want the largest one to be $array1. So, just do a comparison to see which has the most elements.
You have to loop over two arrays to get desired result: as you have to match epg_channel_id of first array to second arrays inner key
$arr1 = Array
(
0 => Array
(
"num" => 1,
"name" => "name 1",
"epg_channel_id" => "ch111",
"added" => "1505435915",
),
1 => Array
(
"num" => 2,
"name" => "name 2",
"epg_channel_id" => "ch222",
"added" => "1505435915",
),
2 => Array
(
"num" => 3,
"name" => "name 3",
"epg_channel_id" => "ch333",
"added" => "1505435915",
),
3 => Array
(
"num" => 4,
"name" => "name 4",
"epg_channel_id" => "ch444",
"added" => "1505435915",
),
);
$arr2 = Array
(
0 => Array
(
"ch000" => "Um9jayBJbiBSaW8="
),
1 => Array
(
"ch111" => "Um9jayBJbiBSaW8="
),
2 => Array
(
"ch222" => "Um9jayBJbiBSaW8="
),
3 => Array
(
"ch333" => "Um9jayBJbiBSaW8="
),
4 => Array
(
"ch444" => "Um9jayBJbiBSaW8="
),
);
$new_array = array();
foreach($arr1 as $key=>$value)
{
foreach($arr2 as $key1=>$value1)
{
foreach($value1 as $key2=>$value2)
{
if($key2 == $value['epg_channel_id'])
{
$value[$key2]=$value2;
}
}
}
$new_array[$key]=$value;
}
print_r($new_array);
DEMO
You can key exists or not using array_key_exists in second array then add it to new array
Working Demo: https://eval.in/863359
$array = Array
(
Array
(
'num' => 1,
'name' => 'name 1',
'epg_channel_id' => 'ch111',
'added' => '1505435915',
),
Array
(
'num' => 2,
'name' => 'name 2',
'epg_channel_id' => 'ch222',
'added' => '1505435915',
),
Array
(
'num' => 3,
'name' => 'name 3',
'epg_channel_id' => 'ch333',
'added' => '1505435915',
),
Array
(
'num' => 4,
'name' => 'name 4',
'epg_channel_id' => 'ch444',
'added' => '1505435915'
)
);
$array2 = Array
(
Array
(
'ch000' => 'Um9jayBJbiBSaW8='
),
Array
(
'ch111' => 'Um9jayBJbiBSaW8='
),
Array
(
'ch222' => 'Um9jayBJbiBSaW8='
),
Array
(
'ch333' => 'Um9jayBJbiBSaW8='
),
Array
(
'ch444' => 'Um9jayBJbiBSaW8='
)
);
$newArray =[];
foreach ($array as $key => $value) {
foreach ($array2 as $key2 => $value2) {
if (array_key_exists($value['epg_channel_id'], $value2)) {
$value[$value['epg_channel_id']] = $value2[$value['epg_channel_id']];
}
}
$newArray[] = $value;
}
echo "<pre>";
print_r($newArray);
array_merge_recursive works well for associated array that have keys are string. Numeric keys will be appended. From php.net
If the input arrays have the same string keys, then the values for these keys are merged together into an array, and this is done recursively, so that if one of the values is an array itself, the function will merge it with a corresponding entry in another array too. If, however, the arrays have the same numeric key, the later value will not overwrite the original value, but will be appended.
You have to convert your array to string keys, or using one loop to merge child arrays one by one.
Try this . I hope it will solve your problems. I have tested it.
foreach ($array1 as $key => $value){
// echo $key;
foreach ($array2 as $i =>$item){
foreach ($item as $j=>$subitem){
if($value['epg_channel_id'] == $j){
$array1[$key][$j] = $subitem;
}
}
}
}
print_r($array1);
try to read the value of 'epg_channel_id' from array1
and insert it to array1 itself from getting 'ch111' from array2
$ch_name = $array1[$i]['epg_channel_id'];
$id = $array1[$i]['num'];
$ch_value = $array2[$id]['$ch_name'];
$array1[$i]["$ch_name"] = $ch_value;
try to put in foreach for every array
$new_arr = [];
foreach($arr1 as $val){
foreach($arr2 as $val2){
if(array_key_exists($val['epg_channel_id'], $val2)){
$val[$val['epg_channel_id']] = $val2[$val['epg_channel_id']];
break;
}
}
$new_arr[] = $val;
}
print_r($new_arr);
The bad news is that your second array is not suitably structured to serve as a lookup array. The good news is that the step to flatten the structure into a simple associative array is quite easy.
Once the lookup is declared, just use a loop and modify-by-reference as you use array union syntax to append the desired key-value pairs.
I do not recommend any answers that are using nested loops -- they will not perform efficiently.
Code: (Demo)
$lookup = array_merge(...$array2);
foreach ($array as &$row) {
$row += [$row['epg_channel_id'] => $lookup[$row['epg_channel_id']]];
}
var_export($array);
I have 2 arrays, one with key, another with numeric keys, how can i copy they key, replacing the numeric keys in the exact order?
Array with numeric key
Array
(
[0] => ABCDEFG
[1] => This is my description
[2] => 12.00
[3] => 30.00
[4] => My supplier
[5] => My brand
[6] => Shoes
[7] =>
)
Array 2
Array
(
[productcode] => Product Code
[productitemdesc] => Description
[retailsalesprice] => Selling Price
[currentcost] => Unit Cost
[supplier] => Supplier
[productbrand] => Brand
[productcategory] => Category
[productgroup] => Group
)
I would want something like this
Array
(
[productcode] => ABCDEFG
[productitemdesc] => This is my description
[retailsalesprice] => 12.00
[currentcost] => 30.00
[supplier] => My Supplier
[productbrand] => My Brand
[productcategory] => Shoes
[productgroup] =>
)
Is there any existing functions available for php? Tried array_fill_keys but doesn't seem to be what i want.
You can use the function array_combine() to combine the keys from the second array (for the following example called $array_keys) with the values from the first array (called $array_values):
Example:
$combined = array_combine(array_keys($array_keys), $array_values);
print_r($combined);
This prints out the array exactly like you described.
array_combine way is a lot better but you can use this function as well. This will allow you to modify the values if you want.
function custom_combine($numeric_array, $keyed_array)
{
$temp = array();
$i=0;
foreach($keyed_array as $key=>$val)
{
if(isset($numeric_array[$i]))
$temp[$key] = $numeric_array[$i];
else
$temp[$key] ='';
$i++;
}
return($temp);
}
The other answers are definitely more efficient, but in case you'd like to learn how to manually loop through arrays, something like this should work:
<?php
// The original array
$arr1 = array(
0 => 'ABCDEFG',
1 => 'This is my description',
2 => '12.00',
3 => '30.00',
4 => 'My supplier',
5 => 'My brand',
6 => 'Shoes',
7 => '',
);
// The second array
$arr2 = array(
'productcode' => 'Product Code',
'productitemdesc' => 'Description',
'retailsalesprice' => 'Selling Price',
'currentcost' => 'Unit Cost',
'supplier' => 'Supplier',
'productbrand' => 'Brand',
'productcategory' => 'Category',
'productgroup' => 'Group',
);
// Pre-define the new array to avoid errors
$arr_new = array();
// Manually create a value to increment during our foreach loop
$increment = 0;
// Loop through each value in $arr2
foreach ($arr2 as $key2 => $value2) {
// If the key is set in $arr1, assign the value from $arr1 and the key from $arr2
// to the new array
if (isset($arr1[$increment])) {
$arr_new[$key2] = $arr1[$increment];
}
// Increment the value regardless of whether it was found in $arr1 or not
$increment++;
}
// Remove this if you want... It just displays the values found in $arr_new
print_r($arr_new);
i tested it and work :
<?php
$a=array(
0 => "ABCDEFG",
1 => "This is my description",
2 => "12.00",
3 => '30.00',
4 => 'My supplier',
5 => 'My brand',
6 => 'Shoes',
7 => '',
)
;
$b=array
(
'productcode' => 'Product Code',
'productitemdesc' => 'Description',
'retailsalesprice' => 'Selling Price',
'currentcost' => 'Unit Cost',
'supplier' => 'Supplier',
'productbrand' => 'Brand',
'productcategory' => 'Category',
'productgroup' => 'Group',
);
$j=0;
foreach ($b as $i => $value) {
$b[$i]=$a[$j];
$j++;
}
var_dump($b);
?>
you can use array_combine()
$array3=array_combine($array2,$array1);
print_r($array3);
I need your help with my problem. My problem is I have 2 arrays the first one is the main array. The second is the array for my new data.
Let's say I have these arrays.
This is the main array:
Array
(
0 => Array
(
'id' => 1,
'name' => 'Apple',
'age' => 12
)
1 => Array
(
'id' => 2,
'name' => May,
'age' => 13
)
)
This is the second array:
Array
(
1 => Array
(
'gender' => 'Male'
)
2 => Array
(
'gender' => 'Female'
)
)
And I have this loop in PHP
foreach($main_array as &$main){
//this is the loop inside the first array
// how can I add the second array with it?
}
This is the sample output:
[0] => Array
(
[id] => 1
[name] => Apple
[age] => 12
[gender] => Female
)
[1] => Array
(
[id] => 2
[name] => May
[age] => 13
[gender] => Female
)
How can I do that? Any suggestions? That's all thanks.
for($i=0; $i<count($main_array); $i++){
for($j=0; $j<count($second_array); $j++){
if($main_array[$i]['id'] == $j){
$main_array[$i]['gender'] = $second_array[$j]['gender']
}
}
}
I fixed your example code, it wont run otherwise.
<?php
// Test data:
$main_array = Array(
0 => Array(
'id' => 1,
'name' => 'Apple',
'age' => 12
),
1 => Array (
'id' => 2,
'name' => 'May',
'age' => 13
)
);
$lookup = Array(
1 => Array(
'gender' => 'Male'
),
2 => Array(
'gender' => 'Female'
)
);
// Your answer:
foreach ($main_array as &$main) {
if (array_key_exists($main['id'],$lookup)) {
$main['gender'] = $lookup[$main['id']]['gender']; // <-- sets gender value
}
}
// Output it to browser:
echo '<pre>$main_array = '.print_r($main_array,true).'</pre>';
The array_key_exists() check is there to avoid errors such as PHP Notice: Undefined offset: 123 when the $lookup data is incomplete.
If you want to merge all of the data from both arrays:
PHP tools:
The exact behaviors of these functions needs to be studied and tested before usage, to make sure it fits your intent.
// array merge recursive doesn't merge numeric keys
$main_array = array_merge_recursive($main_array, $secondary_array);
// array replace recursive has a downside of replacing stuff
$main_array = array_replace_recursive($main_array, $secondary_array);
Rolling your own:
foreach($main_array as $i => &$main){
if(isset($secondary_array[$i])) {
foreach($secondary_array[$i] AS $key => $value) {
$main[$key] = $value;
}
}
}
Both of the above solutions only apply if the array-indexes of $main_array and $secondary_array match.
In your example your arrays don't match:
- $secondary_array[0] doesn't exist so $main_array[0] will not be populated with a 'gender' value;
- $main_array[2] doesn't exist so $main_array[2] will be created and it will only have a 'gender' value same as $secondary_array[2]['gender']
If you want to only merge some bits and pieces of the arrays:
Rolling your own:
foreach($main_array as $i => &$main) {
if(isset($secondary_array[$i])) and isset($secondary_array[$i]['gender'])) {
$main['gender'] = $secondary_array[$i]['gender'];
}
}
foreach($main_array as &$main){//this is the loop inside the first array
foreach($second_array as &$second){ //this is the loop inside the second array
}
}
foreach($arr1 as $k => $arr1Item) {
$arr1[$k]['gender'] = $arr2[$k]['gender'];
}