Related
I have an array of arrays, with the following structure :
array(array('page' => 'page1', 'name' => 'pagename1')
array('page' => 'page2', 'name' => 'pagename2')
array('page' => 'page3', 'name' => 'pagename3'))
Is there a built-in function that will return a new array with just the values of the 'name' keys? so I'd get:
array('pagename1', 'pagename2', 'pagename3')
As of PHP 5.5 you can use array_column():
<?php
$samples=array(
array('page' => 'page1', 'name' => 'pagename1'),
array('page' => 'page2', 'name' => 'pagename2'),
array('page' => 'page3', 'name' => 'pagename3')
);
$names = array_column($samples, 'name');
print_r($names);
See it in action
Why does it have to be a built in function? No, there is none, write your own.
Here is a nice and easy one, as opposed to others in this thread.
$namearray = array();
foreach ($array as $item) {
$namearray[] = $item['name'];
}
In some cases where the keys aren't named you could instead do something like this
$namearray = array();
foreach ($array as $key => $value) {
$namearray [] = $value;
}
Here's a functional way of doing it:
$data = array(
array('page' => 'page1', 'name' => 'pagename1'),
array('page' => 'page2', 'name' => 'pagename2'),
array('page' => 'page3', 'name' => 'pagename3'));
$result = array_map(create_function('$arr', 'return $arr["name"];'), $data);
print_r($result);
Well there is. At least for PHP > 5.5.0 and it is called array_column
The PHP function takes an optional $index_keyparameter that - as per the PHP website - states:
$index_key
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
In the answers here, i see a stripped version without the optional parameter.
I needed it, so, here is the complete function:
if (!function_exists('array_column')) {
function array_column($array, $column, $index_key = null) {
$toret = array();
foreach ($array as $key => $value) {
if ($index_key === null){
$toret[] = $value[$column];
}else{
$toret[$value[$index_key]] = $value[$column];
}
}
return $toret;
}
}
Similar to fuentesjrs solution, but a bit more generic using array_walk() with a custom callback:
// Define the callback
function extract_named_sub_elements(&$item, $key, $name) {
$item = $item[$name];
}
// Test data
$original = array(
array('page' => 'page1', 'name' => 'pagename1'),
array('page' => 'page2', 'name' => 'pagename2'),
array('page' => 'page3', 'name' => 'pagename3'),
);
// Use a copy, as array_walk() operates directly on the passed in array
$copy = $original;
// Substitute 'name' with whatever element you want to extract, e.g. 'page'
array_walk($copy, 'extract_named_sub_elements', 'name');
print_r($copy);
if (!function_exists('array_column')) {
function array_column($array,$column) {
$col = array();
foreach ($array as $k => $v) {
$col[]=$v[$column];
}
return $col;
}
}
This should work for php versions < 5.5 and degrade in case the function exist
Yes, there is a php built-in function called array_column which does what you are looking for.
You would call it something like $name_keys = array_column($array, 'name'); to get the result that you are looking for.
Please refer to the following entry in the PHP manual for more details:
http://php.net/manual/en/function.array-column.php
You can extend the ArrayIterator class and override the method mixed current(void).
class Foo extends ArrayIterator {
protected $index;
public function __construct($array, $index) {
parent::__construct($array);
$this->index = $index;
}
public function current() {
$c = parent::current();
return isset($c[$this->index]) ? $c[$this->index] : null;
}
}
$a = array(
array('page' => 'page1', 'name' => 'pagename1'),
array('name' => '---'),
array('page' => 'page2', 'name' => 'pagename2'),
array('page' => 'page3', 'name' => 'pagename3')
);
$f = new Foo($a, 'page');
foreach($f as $e) {
echo $e, "\n";
}
prints
page1
page2
page3
I don't think there is any need to have a built in function for this.
There may be an array in your those array.
$samples=array(
array('page' => 'page1', 'name' => 'pagename1'),
array('page' => 'page2', 'name' => 'pagename2'),
array('page' => 'page3', 'name' => 'pagename3')
);
$output1=array();
$output2=array();
foreach($samples as $sample){
array_push($output1,$sample['name']);
$output2[]=array_splice($sample,1);
}
print_r($output1);
print_r($output2);
in $output1 is the output what you want if you want only to remove the 'page' indexing' part then $output2.
if you need all the values from the that array and indexes numerically the array then you can use
$array_1=array_values($samples);
but what i understand, you didn't want this.
There is a built-in function actually, it's called array_column(...).
Here is all you need to know about it : https://www.php.net/manual/fr/function.array-column.php
Not a 'built-in', but short arrow functions make for abrreviated explicit coding (introduced in Php v7.4.) and can be used with array_map for array transformations.
Here applying a callback to each member of the array that returns the desired attribute from each subarray:
<?php
$data =
[
['page' => 'page1', 'name' => 'pagename1'],
['page' => 'page2', 'name' => 'pagename2'],
['page' => 'page3', 'name' => 'pagename3']
];
$names = array_map(fn($v) => $v['name'], $data);
var_export($names);
Output:
array (
0 => 'pagename1',
1 => 'pagename2',
2 => 'pagename3',
)
The OP posted this question before array_column exisited (from Php 5.5.0). This answers the original question with a short solution:
$names = array_column($data, 'name');
But a simple loop is also trite:
foreach($data as $item) $names[] = $item['name'];
With array_reduce:
$names = array_reduce($array, function ($carry, $item) {
return array_merge($carry, [$item['name']]);
}, []);
You can get column, bind key value as well:
$a = array(
array(
'id' => 5698,
'first_name' => 'Peter',
'last_name' => 'Griffin',
),
array(
'id' => 4767,
'first_name' => 'Ben',
'last_name' => 'Smith',
),
array(
'id' => 3809,
'first_name' => 'Joe',
'last_name' => 'Doe',
)
);
if you want only column then use:
$last_names = array_column($a, 'last_name');
print_r($last_names);
if you want to bind key and values then use:
$last_names = array_column($a, 'last_name', 'id');
print_r($last_names);
Just to extend on some of the answers here, as of PHP 5.5, array_column is what you want.
It actually has a few possible uses.
Using the sample array below, here are the different ways to use array_column.
$a = array(
array('id' => '1', 'name' => 'Joe'),
array('id' => '2', 'name' => 'Jane')
);
Retrieving a single column as the array
$b = array_column($a, 'name');
Would give you. Notice the auto keys starting from 0, as per a normal array.
$b[0] = 'Joe';
$b[1] = 'Jane';
Retrieving the full array with a column as the index.
$c = array_column($a, NULL, 'id');
Would result in the following.
$c[1] = array('id' => '1', 'name' => 'Joe');
$c[2] = array('id' => '2', 'name' => 'Jane');
Notice how the column I selected as the third parameter becomes the key for each item and I get the full array by setting the second parameter to null.
Of course, the final usage is to set both the 2nd and 3rd params.
$d = array_column($a, 'name', 'id');
Would give you the following.
$d[1] = 'Joe';
$d[2] = 'Jane';
I personally use the full 3 params for creating select option lists. If I have a table with my options, I query the table and get the result and pass it into this to get a list with the key as the value and the label. This is a brilliant way for building info sets that need to intersect by the index as well.
I wanted to post here, even if this is an old question, because it is still very relevant and many developers do not use PHP >= 5.5
Let's say you have an array like this:
Array
(
[files] => Array
(
[name] => Array
(
[0] => file 1
[1] => file 2
[2] => file 3
)
[size] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
[error] => Array
(
[0] => abc
[1] => def
[2] => ghi
)
)
)
and the output you want is something like this:
Array
(
[0] => Array
(
[0] => file 1
[1] => 1
[2] => abc
)
[1] => Array
(
[0] => file 2
[1] => 2
[2] => def
)
[2] => Array
(
[0] => file 3
[1] => 3
[2] => ghi
)
)
You can simply use the array_map() method without a function name passed as the first parameter, like so:
array_map(null, $a['files']['name'], $a['files']['size'], $a['files']['error']);
Unfortunately you cannot map the keys if passing more than one array.
I'm using array_filter in PHP to split an array containing multiple arrays when the value of a key named type matches a specific string. Here's what this looks like:
Sample Array
$arr[] = Array (
[0] => Array ( [type] => Recurring ... )
[1] => Array ( [type] => Single ... )
)
Functions
function recurring($value)
{
return ($value['type'] == 'Recurring');
}
function single($value)
{
return ($value['type'] == 'Single');
}
Split Arrays
$recurring = array_filter($arr, 'recurring');
$single = array_filter($arr, 'single');
This works, but I was curious if there was a way to simplify it so that I could create additional filtered arrays in the future without creating a new function for each.
I've started setting up a single function using a closure, but I'm not sure how to do it. Any ideas?
function key_type($value, $key, $string) {
return $key == 'type' && $value == $string;
}
$recurring = array_filter($arr,
key_type('Recurring'), ARRAY_FILTER_USE_BOTH);
$single = array_filter($pricing,
key_type('Single'), ARRAY_FILTER_USE_BOTH);
You could actually do what you proposed in your question. You just need to have the key_type() function return a callable function, which is what array_filter expects as the second parameter. You can return an anonymous function and pass the argument into the anonymous function using the use keyword as CBroe mentioned in the comments.
Here is an example:
function key_type($key) {
return function($value) use ($key) {
return $value['type'] == $key;
};
}
$arr = array(
array('type'=>'Recurring'),
array('type'=>'Single')
);
print_r(array_filter($arr, key_type('Single'), ARRAY_FILTER_USE_BOTH));
The above code will output:
Array ( [1] => Array ( [type] => Single ) )
The beauty of this method is that if you need to change the logic for all instances where you need to use your filter, you just have to change it one time in your key_type function.
An approach would be like below, however I don't like it honestly.
$array = [['type' => 'Single'], ['type' => 'Recurring']];
function key_type($value) {
global $string;
return $value['type'] == $string;
}
($string = 'Recurring') && ($recurring = array_filter($array, 'key_type'));
($string = 'Single') && ($single = array_filter($array, 'key_type'));
Another way to achieve same thing is using Anonymous functions (closures). Don't think much about being DRY it seems nice:
$array = [['type' => 'Single'], ['type' => 'Recurring']];
$recurring = array_filter($array, function($value) {
return $value['type'] == 'Recurring';
});
$single = array_filter($array, function($value) {
return $value['type'] == 'Single';
});
This task might be more about grouping than filtering -- it is difficult to discern from the limited sample data.
As a general rule, I strongly advise against using variable variables in PHP code. It is better practice to store data in arrays for accessibility reasons.
If you only have the two mentioned type values in your project data, then the conditional can be removed entirely.
Code: (Demo)
$array = [
['type' => 'Recurring', 'id' => 1],
['type' => 'Single', 'id' => 2],
['type' => 'Other', 'id' => 3],
['type' => 'Recurring', 'id' => 4],
['type' => 'Single', 'id' => 5],
];
$result = [];
foreach ($array as $row) {
if (in_array($row['type'], ['Recurring', 'Single'])) {
$result[strtolower($row['type'])][] = $row;
}
}
var_export($result);
Output:
array (
'recurring' =>
array (
0 =>
array (
'type' => 'Recurring',
'id' => 1,
),
1 =>
array (
'type' => 'Recurring',
'id' => 4,
),
),
'single' =>
array (
0 =>
array (
'type' => 'Single',
'id' => 2,
),
1 =>
array (
'type' => 'Single',
'id' => 5,
),
),
)
I have an array of arrays, with the following structure :
array(array('page' => 'page1', 'name' => 'pagename1')
array('page' => 'page2', 'name' => 'pagename2')
array('page' => 'page3', 'name' => 'pagename3'))
Is there a built-in function that will return a new array with just the values of the 'name' keys? so I'd get:
array('pagename1', 'pagename2', 'pagename3')
As of PHP 5.5 you can use array_column():
<?php
$samples=array(
array('page' => 'page1', 'name' => 'pagename1'),
array('page' => 'page2', 'name' => 'pagename2'),
array('page' => 'page3', 'name' => 'pagename3')
);
$names = array_column($samples, 'name');
print_r($names);
See it in action
Why does it have to be a built in function? No, there is none, write your own.
Here is a nice and easy one, as opposed to others in this thread.
$namearray = array();
foreach ($array as $item) {
$namearray[] = $item['name'];
}
In some cases where the keys aren't named you could instead do something like this
$namearray = array();
foreach ($array as $key => $value) {
$namearray [] = $value;
}
Here's a functional way of doing it:
$data = array(
array('page' => 'page1', 'name' => 'pagename1'),
array('page' => 'page2', 'name' => 'pagename2'),
array('page' => 'page3', 'name' => 'pagename3'));
$result = array_map(create_function('$arr', 'return $arr["name"];'), $data);
print_r($result);
Well there is. At least for PHP > 5.5.0 and it is called array_column
The PHP function takes an optional $index_keyparameter that - as per the PHP website - states:
$index_key
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
In the answers here, i see a stripped version without the optional parameter.
I needed it, so, here is the complete function:
if (!function_exists('array_column')) {
function array_column($array, $column, $index_key = null) {
$toret = array();
foreach ($array as $key => $value) {
if ($index_key === null){
$toret[] = $value[$column];
}else{
$toret[$value[$index_key]] = $value[$column];
}
}
return $toret;
}
}
Similar to fuentesjrs solution, but a bit more generic using array_walk() with a custom callback:
// Define the callback
function extract_named_sub_elements(&$item, $key, $name) {
$item = $item[$name];
}
// Test data
$original = array(
array('page' => 'page1', 'name' => 'pagename1'),
array('page' => 'page2', 'name' => 'pagename2'),
array('page' => 'page3', 'name' => 'pagename3'),
);
// Use a copy, as array_walk() operates directly on the passed in array
$copy = $original;
// Substitute 'name' with whatever element you want to extract, e.g. 'page'
array_walk($copy, 'extract_named_sub_elements', 'name');
print_r($copy);
if (!function_exists('array_column')) {
function array_column($array,$column) {
$col = array();
foreach ($array as $k => $v) {
$col[]=$v[$column];
}
return $col;
}
}
This should work for php versions < 5.5 and degrade in case the function exist
Yes, there is a php built-in function called array_column which does what you are looking for.
You would call it something like $name_keys = array_column($array, 'name'); to get the result that you are looking for.
Please refer to the following entry in the PHP manual for more details:
http://php.net/manual/en/function.array-column.php
You can extend the ArrayIterator class and override the method mixed current(void).
class Foo extends ArrayIterator {
protected $index;
public function __construct($array, $index) {
parent::__construct($array);
$this->index = $index;
}
public function current() {
$c = parent::current();
return isset($c[$this->index]) ? $c[$this->index] : null;
}
}
$a = array(
array('page' => 'page1', 'name' => 'pagename1'),
array('name' => '---'),
array('page' => 'page2', 'name' => 'pagename2'),
array('page' => 'page3', 'name' => 'pagename3')
);
$f = new Foo($a, 'page');
foreach($f as $e) {
echo $e, "\n";
}
prints
page1
page2
page3
I don't think there is any need to have a built in function for this.
There may be an array in your those array.
$samples=array(
array('page' => 'page1', 'name' => 'pagename1'),
array('page' => 'page2', 'name' => 'pagename2'),
array('page' => 'page3', 'name' => 'pagename3')
);
$output1=array();
$output2=array();
foreach($samples as $sample){
array_push($output1,$sample['name']);
$output2[]=array_splice($sample,1);
}
print_r($output1);
print_r($output2);
in $output1 is the output what you want if you want only to remove the 'page' indexing' part then $output2.
if you need all the values from the that array and indexes numerically the array then you can use
$array_1=array_values($samples);
but what i understand, you didn't want this.
There is a built-in function actually, it's called array_column(...).
Here is all you need to know about it : https://www.php.net/manual/fr/function.array-column.php
Not a 'built-in', but short arrow functions make for abrreviated explicit coding (introduced in Php v7.4.) and can be used with array_map for array transformations.
Here applying a callback to each member of the array that returns the desired attribute from each subarray:
<?php
$data =
[
['page' => 'page1', 'name' => 'pagename1'],
['page' => 'page2', 'name' => 'pagename2'],
['page' => 'page3', 'name' => 'pagename3']
];
$names = array_map(fn($v) => $v['name'], $data);
var_export($names);
Output:
array (
0 => 'pagename1',
1 => 'pagename2',
2 => 'pagename3',
)
The OP posted this question before array_column exisited (from Php 5.5.0). This answers the original question with a short solution:
$names = array_column($data, 'name');
But a simple loop is also trite:
foreach($data as $item) $names[] = $item['name'];
With array_reduce:
$names = array_reduce($array, function ($carry, $item) {
return array_merge($carry, [$item['name']]);
}, []);
You can get column, bind key value as well:
$a = array(
array(
'id' => 5698,
'first_name' => 'Peter',
'last_name' => 'Griffin',
),
array(
'id' => 4767,
'first_name' => 'Ben',
'last_name' => 'Smith',
),
array(
'id' => 3809,
'first_name' => 'Joe',
'last_name' => 'Doe',
)
);
if you want only column then use:
$last_names = array_column($a, 'last_name');
print_r($last_names);
if you want to bind key and values then use:
$last_names = array_column($a, 'last_name', 'id');
print_r($last_names);
Just to extend on some of the answers here, as of PHP 5.5, array_column is what you want.
It actually has a few possible uses.
Using the sample array below, here are the different ways to use array_column.
$a = array(
array('id' => '1', 'name' => 'Joe'),
array('id' => '2', 'name' => 'Jane')
);
Retrieving a single column as the array
$b = array_column($a, 'name');
Would give you. Notice the auto keys starting from 0, as per a normal array.
$b[0] = 'Joe';
$b[1] = 'Jane';
Retrieving the full array with a column as the index.
$c = array_column($a, NULL, 'id');
Would result in the following.
$c[1] = array('id' => '1', 'name' => 'Joe');
$c[2] = array('id' => '2', 'name' => 'Jane');
Notice how the column I selected as the third parameter becomes the key for each item and I get the full array by setting the second parameter to null.
Of course, the final usage is to set both the 2nd and 3rd params.
$d = array_column($a, 'name', 'id');
Would give you the following.
$d[1] = 'Joe';
$d[2] = 'Jane';
I personally use the full 3 params for creating select option lists. If I have a table with my options, I query the table and get the result and pass it into this to get a list with the key as the value and the label. This is a brilliant way for building info sets that need to intersect by the index as well.
I wanted to post here, even if this is an old question, because it is still very relevant and many developers do not use PHP >= 5.5
Let's say you have an array like this:
Array
(
[files] => Array
(
[name] => Array
(
[0] => file 1
[1] => file 2
[2] => file 3
)
[size] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
[error] => Array
(
[0] => abc
[1] => def
[2] => ghi
)
)
)
and the output you want is something like this:
Array
(
[0] => Array
(
[0] => file 1
[1] => 1
[2] => abc
)
[1] => Array
(
[0] => file 2
[1] => 2
[2] => def
)
[2] => Array
(
[0] => file 3
[1] => 3
[2] => ghi
)
)
You can simply use the array_map() method without a function name passed as the first parameter, like so:
array_map(null, $a['files']['name'], $a['files']['size'], $a['files']['error']);
Unfortunately you cannot map the keys if passing more than one array.
What I'd like to do is have a function that accepts two arguments, both arrays, the first being a one-dimensional array of varying lengths and the second is a multi-dimensional array of varying depths and lengths. The first array is never associative, the second is always a fully associative array.
This function would return the requested value from the multi-dimensional array as indicated by the first array.
Assume that the first array will always be hand-written and passed to this function. Meaning the developer always knows there is a value to be returned from the multi-dimensional array and would never pass a request to the function where a value did not exist.
I think the code below is the best example at what I'm trying to achieve.
//Example multi-dimensional array
$multi = array(
'fruit' => array(
'red' => array(
'strawberries' => '$2.99/lb',
'apples' => '$1.99/lb'
),
'green' => array(
'honeydew' => '$3.39/lb',
'limes' => '$0.75/lb'
)
),
'vegetables' => array(
'yellow' => array(
'squash' => '$1.29/lb',
'bellpepper' => '$0.99/lb'
),
'purple' => array(
'eggplant' => '$2.39/lb'
)
),
'weeklypromo' => '15% off',
'subscribers' => array(
'user1#email.com' => 'User 1',
'user2#email.com' => 'User 2',
'user3#email.com' => 'User 3',
'user4#email.com' => 'User 4'
)
);
//Example one-dimensional array
$single = array('fruit', 'red', 'apples');
function magicfunc($single, $multi) {
//some magic here that looks something like below
$magic_value = $multi[$single[0]][$single[1]][$single[2]];
return $magic_value;
}
//Examples:
print magicfunc(array('fruit', 'red', 'apples'), $multi);
Output:
$1.99/lb
print magicfunc(array('subscribers', 'user3#email.com'), $multi);
Output:
User 3
print magicfunc(array('weeklypromo'), $multi);
Output:
15% off
This returns the values as requested:
function magicfunc($single, $multi) {
while (true) {
if (!$single) {
break;
}
$searchIndex = array_shift($single);
foreach ($multi as $k => $val) {
if ($k == $searchIndex) {
$multi = $val;
continue 2;
}
}
}
return $multi;
}
Say for example you just queried a database and you recieved this 2D array.
$results = array(
array('id' => 1, 'name' => 'red' , 'spin' => 1),
array('id' => 2, 'name' => 'green', 'spin' => -1),
array('id' => 3, 'name' => 'blue' , 'spin' => .5)
);
I often find myself writing loops like this.
foreach($results as $result)
$names[] = $result['name'];
My questions is does there exist a way to get this array $names without using a loop? Using callback functions count as using a loop.
Here is a more generic example of getting every field.
foreach($results as $result)
foreach($result as $key => $value)
$fields[$key][] = $value;
As of June 20th in PHP-5.5 there is a new function array_column
For example:
$records = array(
array(
'id' => 2135,
'first_name' => 'John',
'last_name' => 'Doe'
),
array(
'id' => 3245,
'first_name' => 'Sally',
'last_name' => 'Smith'
),
array(
'id' => 5342,
'first_name' => 'Jane',
'last_name' => 'Jones'
),
array(
'id' => 5623,
'first_name' => 'Peter',
'last_name' => 'Doe'
)
);
$firstNames = array_column($records, 'first_name');
print_r($firstNames);
Will return
Array
(
[0] => John
[1] => Sally
[2] => Jane
[3] => Peter
)
There are even more examples in the above mentioned link.
I voted #Devon's response up because there really isn't a way to do what you're asking with a built-in function. The best you can do is write your own:
function array_column($array, $column)
{
$ret = array();
foreach ($array as $row) $ret[] = $row[$column];
return $ret;
}
Starting PHP 5.3, you can use this pretty call with lambda function:
$names = array_map(function ($v){ return $v['name']; }, $results);
This will return array sliced by 'name' dimension.
Simply put, no.
You will need to use a loop or a callback function like array_walk.
I did more research on this and found that ruby and prototype both have a function that does this called array_pluck,2. It's interesting that array_map has a second use that allows you to do the inverse of what i want to do here. I also found a PHP class someone is writing to emulate prototypes manipulation of arrays.
I'm going to do some more digging around and if I don't find anything else I'll work on a patch to submit to the internals#lists.php.net mailing list and see if they will add array_pluck.
For those of you that cannot upgrade to PHP5.5 right now and need this function, here is an implementation of array_column.
function array_column($array, $column){
$a2 = array();
array_map(function ($a1) use ($column, &$a2){
array_push($a2, $a1[$column]);
}, $array);
return $a2;
}
If you are running a version of PHP before 5.5 and array_column(), you can use the official replacement in plain PHP:
https://github.com/ramsey/array_column
I think this will do what you want
array_uintersect_uassoc
You would have to do something like this
$results = array(
array('id' => 1, 'name' => 'red' , 'spin' => 1),
array('id' => 2, 'name' => 'green', 'spin' => -1),
array('id' => 3, 'name' => 'blue' , 'spin' => .5)
);
$name = array_uintersect_uassoc( $results, array('name' => 'value') , 0, "cmpKey");
print_r($name);
//////////////////////////////////////////////////
// FUNCTIONS
//////////////////////////////////////////////////
function cmpKey($key1, $key2) {
if ($key1 == $key2) {
return 0;
} else {
return -1;
}
}
However, I don't have access to PHP5 so I haven't tested this.
You could do:
$tmp = array_flip($names);
$names = array_keys($tmp);
This is fast function alternative of array_column()
if(!function_exists('array_column')) {
function array_column($element_name) {
$ele = array_map(function($element) {
return $element[$element_name];
}, $a);
return $ele;
}
}
other alternative
function transpose(array $array): array
{
$out = array();
foreach ($array as $rowkey => $row) {
foreach ($row as $colkey => $col) {
$out[$colkey][$rowkey] = $col;
}
}
return $out;
}
function filter_columns(array $arr, string ...$columns): array
{
return array_intersect_key($arr, array_flip($columns));
}
test
$results = array(
array('id' => 1, 'name' => 'red' , 'spin' => 1),
array('id' => 2, 'name' => 'green', 'spin' => -1),
array('id' => 3, 'name' => 'blue' , 'spin' => .5)
);
var_dump(filter_columns(transpose($results),'name'));
var_dump(filter_columns(transpose($results),'id','name'));
var_dump(filter_columns(transpose($results),'id','spin'));