There is custom function to achieve this,
public function filterArrayByKeys(array $input, array $column_keys)
{
$result = array();
$column_keys = array_flip($column_keys); // getting keys as values
foreach ($input as
val) {
// getting only those key value pairs, which matches $column_keys
$result[$key] = array_intersect_key(
column_keys);
}
return $result;
}
this->filterArrayByKeys($students, ['id','name','email']);
print_r($a);
array_flip — Exchanges all keys with their associated values in an array
array_intersect_key — Computes the intersection of arrays using keys for comparison
Output
Array
(
[0] => Array
(
[id] => 498
[name] => Andrew A. Blaine
[email] => [email protected]
)
[1] => Array
(
[id] => 499
[name] => Billie C. Heath
[email] => [email protected]
)
)
Working demo.
Source.
Answer from Rahul on Stack OverflowTry the following function.
function my_merge_array( $arr = [] ){
$result = [];
foreach ( $arr as $_arr ) {
$A = $_arr['A'];
foreach ($_arr['B'] as $key => $value) {
$result[$A][$key] = [ $value, $_arr['C'][$key] ];
}
}
return $result;
}
print_r( my_merge_array( $oriArr ) );
I wasn't able to do it entirely with array_column, but this works ... as long as the product and item arrays have the same number of elements.
<?php
$oriArr = array(
2 => array(
'A' => 'Mapping item1',
'B' => array(1 => 'product1', 2 => 'product2', 3 => 'product3'),
'C'=>array(1 => 'item1', 2 => 'item2', 3 => 'item3')
),
3 => array(
'A' => 'Mapping item2',
'B' => array(1 => 'product4', 2 => 'product5', 3 => 'product6'),
'C'=>array(1 => 'item4', 2 => 'item5', 3 => 'item6')
)
);
$keys = array_column($oriArr,'A');
$products = array_column($oriArr,'B','A');
$items = array_column($oriArr,'C','A');
$result = [];
foreach ($keys as $k) {
$result[$k] = [];
if (isset($products[$k])) {
$i = 1;
foreach ($products[$k] as $p) {
$result[$k][] = [$products[$k][$i],$items[$k][$i]];
$i++;
}
}
}
var_dump($keys,$products,$items);
var_dump($result);
If you need two columns from an array where one is SKU (which generally is unique) then you can use array_column with the third parameter.
$new = array_column($arr, "product_id", "product_sku");
This will return a flat array with the SKU as the key and ID as value making the array easy to work with also.
Output:
array(3) {
[6500722]=>
string(4) "1138"
[6501046]=>
string(4) "1144"
[6294915]=>
string(3) "113"
}
https://3v4l.org/UDGiO
I think the bigger issue is you lose the keys
Original Code
array (
0 =>
array (
0 => '1138',
1 => '6500722',
),
1 =>
array (
0 => '1144',
1 => '6501046',
),
2 =>
array (
0 => '113',
1 => '6294915',
);
You can use a simple foreach instead of the second array_map:
function colsFromArray(array $array, $keys)
{
if (!is_array($keys)) $keys = [$keys];
return array_map(function ($el) use ($keys) {
$o = [];
foreach($keys as $key){
// if(isset($el[$key]))$o[$key] = $el[$key]; //you can do it this way if you don't want to set a default for missing keys.
$o[$key] = isset($el[$key])?$el[$key]:false;
}
return $o;
}, $array);
}
Output
array (
0 =>
array (
'product_id' => '1138',
'product_sku' => '6500722',
),
1 =>
array (
'product_id' => '1144',
'product_sku' => '6501046',
),
2 =>
array (
'product_id' => '113',
'product_sku' => '6294915',
),
)
Sandbox
the problem is that it seems too laggy, since it iterates twice over this.
There is no real way to not iterate over it 2 times, but you probably don't want to throw away the keys either.
That said you can recursively unset the items you don't want.
function colsFromArray(array &$array, $keys)
{
if (!is_array($keys)) $keys = [$keys];
foreach ($array as $key => &$value) {
if (is_array($value)) {
colsFromArray($value, $keys); //recursive
}else if(!in_array($key, $keys)){
unset($array[$key]);
}
}
}
colsFromArray($array, array("product_id", "product_sku"));
var_export($array);
Same output as before
This is easier to do by reference. Rather or not that is faster you'll have to test the 2 and see.
Sandbox
As a final note you shouldn't assume the key will exist or that keys will be an array unless you type cast it as an array.
You could also do it with array filter
function colsFromArray(array $array, $keys)
{
if (!is_array($keys)) $keys = [$keys];
$filter = function($k) use ($keys){
return in_array($k,$keys);
};
return array_map(function ($el) use ($keys,$filter) {
return array_filter($el, $filter, ARRAY_FILTER_USE_KEY );
}, $array);
}
There is some small performance benefit to declaring the function for filtering outside of the loop (array_map).
Sandbox
From your code it seems like you wanna keep keys corresponding to its value correctly after you use array_column twice.
But for you information you can get this by using array_column just once like this:
$items = array_column($array, 'qty', 'id')
Now you get an associative array whose keys are each row’s id and values are each row’s qty.
The third parameter's meaning of array_column is
The column to use as the index/keys for the returned array. This value may be the integer key of the column, or it may be the string key name.
You can find more explains and examples from documentation: http://php.net/manual/en/function.array-column.php
Since the DB result is row-based (usually), every column will have some value (even if it's NULL). So unless you mess with the result somehow, you should be safe. I do practically the same in some of my code.