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);
Related
I have a working delivery system that I need to present in alphabetical order sorted by the city, which is the key in a subarray.
This is the array:
array (
'option_3' => array (
'Rio' => '18',
),
'option_4' => array (
'Tokyo' => '20',
),
'option_5' => array (
'Berlim' => '23',
)
)
And it is shown in this table:
<table>
<tr>
<th>ID</th>
<th>Bairro</th>
<th>Valor</th>
<th>Ação</th>
</tr>
[a foreach goes here]
<tr>
<td><?php echo $option_number;?></td>
<td><?php echo $city;?></td>
<td><?php echo $price;?></td>
<td><button type='submit'>Remove</button></td>
</tr>
<table>
This produces the folowing result:
ID City Value Action
3 Rio 18 Remover
4 Tokyo 20 Remover
5 Berlim 23 Remover
But I need it to be sorted by the city:
ID City Value Action
5 Berlim 23 Remover
3 Rio 18 Remover
4 Tokyo 20 Remover
How could I accomplish this?
You need to preserve the outer keys, use uasort(). I prefer the spaceship (3-way comparison) operator between two key() calls.
Code: (Demo)
$options = [
'option_3' => [
'Rio' => '18',
],
'option_4' => [
'Tokyo' => '20',
],
'option_5' => [
'Berlim' => '23',
]
];
uasort($options, function ($a, $b) {
return key($a) <=> key($b);
});
var_export($options);
Output:
array (
'option_5' =>
array (
'Berlim' => '23',
),
'option_3' =>
array (
'Rio' => '18',
),
'option_4' =>
array (
'Tokyo' => '20',
),
)
From PHP7.4+, You can use arrow syntax inside custom functions. (Demo)
uasort($options, fn($a, $b) => key($a) <=> key($b));
Preparing for an array_multisort() call is prohibitively hideous, IMO. (Demo)
array_multisort(array_keys(array_merge(...array_values($options))), $options);
Firstly, create a single array for each city and push them into a new array like that:
$options = [
'option_3' => [
'Rio' => '18',
],
'option_4' => [
'Tokyo' => '20',
],
'option_5' => [
'Berlim' => '23',
]
];
$newOptions = [];
foreach($options as $key => $option) {
array_push($newOptions, [
'id' => $key,
'city' => key($option),
'price' => reset($option)
]);
}
After, just sort it alphabetically by the value of each 'city' using usort()
usort($newOptions, function($a, $b) {
return strcmp($a['city'], $b['city']);
});
Finally, you can simply do a foreach into $newOptions and echo whatever you want based on keys 'id', 'city' and 'price'. Example:
foreach($newOptions as $option)
<tr>
<td><?php echo $option['id'];?></td>
<td><?php echo $option['city']?></td>
<td><?php echo $option['price']?></td>
<td><button type='submit'>Remove</button></td>
</tr>
Ok, this sort is little trickier as we need to preserve the parent key for each city as well. So, we go as follows:
Modify the current array to have an extra parent_key in it's subarray which would look like:
'option_3' => array (
'Rio' => '18',
'parent_key' => 'option_3'
)
Now, we use usort() to compare the 2 subarrays via name through strcmp() and return the result.
We again iterate through them and use array_keys() to iterate over the data set. We do this as we are going to restore the parent key back without running into concurrent modification issue while iterating over the same array.
Code:
<?php
$data = array (
'option_3' => array (
'Rio' => '18',
),
'option_4' => array (
'Tokyo' => '20',
),
'option_5' => array (
'Berlim' => '23',
)
);
foreach($data as $key => &$value){
$value['parent_key'] = $key;
}
usort($data,function($val1,$val2){
$name1 = array_keys($val1)[0];
$name2 = array_keys($val2)[0];
return strcmp($name1,$name2);
});
foreach(array_keys($data) as $index){
$value = $data[$index];
$parent_key = $value['parent_key'];
unset($value['parent_key']); // unset parent key now as it is no longer needed
$data[$parent_key] = $value;
unset($data[$index]); // unset numeric index modified by usort()
}
print_r($data);
Demo: https://3v4l.org/q0YFk
Update: Current result does not hold extra keys like city etc, but it is easy to figure that out as a city name while doing a foreach in key-value fashion.
You can accomplish that in many ways, here is my way Demo, hope it works for you.
$arr = array (
'option_3' => array (
'Rio' => '18',
),
'option_4' => array (
'Tokyo' => '20',
),
'option_5' => array (
'Berlim' => '23',
)
);
$cities = [];
foreach($arr as $key=>$val){
foreach($val as $key2=>$city){
$option = explode('_', $key);
$cities[$key2] = $city.'_'.$option[1];
}
}
ksort($cities);
$res = [];
foreach($cities as $key=>$val){
$temp = [];
$temp['city'] = $key;
$val_opt = explode('_', $val);
$temp['value'] = $val_opt[0];
$temp['option'] = $val_opt[1];
$res[] = $temp;
}
print_r($res);
Output:
Array
(
[0] => Array
(
[city] => Berlim
[value] => 23
[option] => 5
)
[1] => Array
(
[city] => Rio
[value] => 18
[option] => 3
)
[2] => Array
(
[city] => Tokyo
[value] => 20
[option] => 4
)
)
I have one array with state codes and their full names, like this:
$first_array=array("AB"=>"Alberta","BC"=>"British Columbia");
I have another array with ids and state codes, like this:
$result_array=array(15=>array("ad_id"=>15,"state code"=>"AB"));
I want to replace the state code values in $result_array with the corresponding "full name" in $first_array.
If there is no corresponding value in $first_array then the state code in $result_array should remain unchanged.
This is my expected result:
$result_array=array(15=>array("ad_id"=>15,"state code"=>"Alberta"));
This should work -
$first_array= array("AB"=>"Alberta","BC"=>"British Columbia");
$second_array = array(
15 => array ( 'ad_id' => 15, 'state code' => 'AB' ) ,
16 => array ( 'ad_id' => 16, 'state code' => 'CD' )
);
$new = array_map(function($a) use($first_array) {
return array(
'ad_id' => $a['ad_id'],
'state code' => !empty($first_array[$a['state code']]) ? $first_array[$a['state code']] : $a['state code'],
);
}, $second_array);
print_r($new);
Output
Array
(
[15] => Array
(
[ad_id] => 15
[state code] => Alberta
)
[16] => Array
(
[ad_id] => 16
[state code] => CD
)
)
Input:
$first_array=["AB"=>"Alberta","BC"=>"British Columbia"];
$result_array=[
15=>['ad_id'=>15,'state code'=>'AB'],
16=>['ad_id'=>16,'state code'=>'BC'],
17=>['ad_id'=>17,'state code'=>'NY']
];
Method #1 - array_walk()
array_walk($result_array,function(&$a)use($first_array){
if(isset($first_array[$a['state code']])){ // only overwrite state code if full name is available
$a['state code']=$first_array[$a['state code']];
}
});
Method #2 - foreach()
foreach($result_array as $k=>$a){
if(isset($first_array[$a['state code']])){ // only overwrite state code if full name is available
$result_array[$k]['state code']=$first_array[$a['state code']];
}
}
Output (from either method): var_export($result_array);
array (
15 =>
array (
'ad_id' => 15,
'state code' => 'Alberta',
),
16 =>
array (
'ad_id' => 16,
'state code' => 'British Columbia',
),
17 =>
array (
'ad_id' => 17,
'state code' => 'NY',
),
)
I have an associative array having two different prices with the same id.
Let it be...
Array ( [0] => Array ( [price] => 3800 [id] => 400015 )
[1] => Array ( [price] => 3700 [id] => 400015 )
[2] => Array ( [price] => 3300 [id] => 400018 )
[3] => Array ( [price] => 3000 [id] => 400018 )
[4] => Array ( [price] => 3100 [id] => 400020 )
[5] => Array ( [price] => 3400 [id] => 400020 ))
I need to display them as
id:400015, Price=3800-3700
id:400018, Price=3000-3600
id:400020, Price=3100-3400
use below if array_column doesn't support
$arr = Array ( '0' => Array ( 'price' => 3800, 'id' => 400015 ) ,
'1' => Array ( 'price' => 3700, 'id' => 400015 ),
'2' => Array ( 'price' => 3300, 'id' => 400018 ),
'3' => Array ( 'price' => 3000, 'id' => 400018 ),
'4' => Array ( 'price' => 3100, 'id' => 400020 ),
'5' => Array ( 'price' => 3400, 'id' => 400020 ),);
$new_arr =array();
foreach($arr as $key=>$row){
if(isset($new_arr[$row['id']])){
$new_arr[$row['id']]= $new_arr[$row['id']].'-'.$row['price'];
}else{
$new_arr[$row['id']]=$row['price'];
}
}
foreach($new_arr as $key=>$row){
echo 'id:'.$key.', Price = '.$row.'<br>';
}
You can loop array and create new array which will be easy to create output you want to show
$newArray = array();
foreach($main as $key=>$val){
$newArray[$val['id']][] = $val['price'];
}
foreach ($newArray as $key=>$val){
sort($val,1);
echo 'id: '.$key.', Price='.implode('-', $val).'<br/>';
}
Loop over the array and print out the respective id and price. Not too sure what you are doing with the price subtraction but this should give you what you need.
$array = array(array('price'=>3800, 'id'=>40015),
array('price'=>3700 , 'id'=>40001),
array('price'=>3800, 'id'=>400015),
array('price'=>3300 , 'id'=>400018),
array('price'=>3000 , 'id'=>400018),
array('price'=>3100 , 'id'=>400020),
array('price'=>3400 , 'id'=>400020));
asort($array);
foreach ($array as $key => $value)
{
echo 'id: '.$value['id'].', Price='.$value['price'].'<br />';
}
Just to show a little bit of variance, and use a PHP7 feature:
usort($data, function($a, $b) { return $a['price'] <=> $b['price']; });
$maxPrices = array_column($data, 'price', 'id');
usort($data, function($a, $b) { return $b['price'] <=> $a['price']; });
$minPrices = array_column($data, 'price', 'id');
foreach($minPrices as $id => $minPrice) {
echo 'id:', $id, ', Price=', $minPrice, '-', $maxPrices[$id], PHP_EOL;
}
This uses usort() to order the array by maximum price (using the new "spaceship" operator); then array_column() to create an array of id's and max prices, as where there are matching id's then the price will be overridden by the previous values so that only the highest value matching each id remains in the $maxPrices array; then does similarly for minimum values.
Finally the loop iterates over the min array, fetching each id and minimum price in turn, and does an id lookup to get the maximum price to display
Demo
Note that use of the spaceship operator does require PHP7
$list = array(
array(
'header_name' => '1.',
'header_database_name' => '2',
'heading' => 'personal',
),
array(
'header_name' => '11. ',
'header_database_name' => '22',
'heading' => 'professional',
),
array(
'header_name' => '33',
'header_database_name' => '333',
'heading' => 'personal',
),
);
foreach($list as $li)
{
?>
"> ';}
else ($li['heading'] == 'performance')
{echo $li['header_name'].'';}
}
I need to print this array by grouping it by heading for example the one with heading as personal should be displayed under the personal title i.e:
Personal
1
33
Professional
11
my php code is like this
foreach($list as $li)
{
?>
"> ';}
else ($li['heading'] == 'performance')
{echo $li['header_name'].'';}
}
It is printing by group but i also need heading to be added but only one time at the top for example now if i add heading to it it prints as personal 1
professional 2
peronal 3
but i need as
personal
1
2
professional
2
You need to sort array if you want grouping of data, use usort
function headingSort ($x, $y) {
return strcasecmp($x['heading'], $y['heading']);
}
usort($myArray, 'headingSort');
Use like
$new_array = array();
foreach($list as $k=>$v)
{
if(!in_array($v['header_name'], $new_array))
$new_array[$v['heading']][] = $v['header_name'];
else
$new_array[$v['heading']] = $v['header_name'];
}
print_r($new_array);
Try this :
$list = array(
array(
'header_name' => '1.',
'header_database_name' => '2',
'heading' => 'personal',
),
array(
'header_name' => '11. ',
'header_database_name' => '22',
'heading' => 'professional',
),
array(
'header_name' => '33',
'header_database_name' => '333',
'heading' => 'personal',
)
);
$personal = array();
$professional = array();
for($i=0;$i<count($list);$i++){
if($list[$i]['heading']=="professional"){
array_push($professional,$list[$i]);
}else{
array_push($personal,$list[$i]);
}
}
$new = array(
"personal"=>$personal,
"professional"=>$professional
);
echo "<pre>";
print_r($new);
Result will be like :
Array
(
[personal] => Array
(
[0] => Array
(
[header_name] => 1.
[header_database_name] => 2
[heading] => personal
)
[1] => Array
(
[header_name] => 33
[header_database_name] => 333
[heading] => personal
)
)
[professional] => Array
(
[0] => Array
(
[header_name] => 11.
[header_database_name] => 22
[heading] => professional
)
)
)
The solution using array_column(available since PHP 5.5), array_unique, array_keys and implode functions:
$headings = array_column($list, 'heading', 'header_name');
foreach (array_unique($headings) as $v) {
echo ucfirst($v). PHP_EOL;
echo implode("\n", array_keys($headings, $v)). PHP_EOL;
}
The output:
Personal
1
33
Professional
11
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'];
}