Alternate to array_column() - php

I have used array_column() in a project, and after uploading I found out that only PHP 5.5 or above support this function, and I think the hosting I use don't support PHP 5.5 or above.
So I want to know if is there any alternate to fix this error?
This is how I am using array_count in my project:
array_count_values(array_column(json_decode(json_encode($queryResultArray), true), $idForBar));
This is working fine in my local xampp and wampp also, but on server it is giving issue. Looking any alternate function or solution.

Add your own function array_column if you PHP version does not support it:
<?php
if (! function_exists('array_column')) {
function array_column(array $input, $columnKey, $indexKey = null) {
$array = array();
foreach ($input as $value) {
if ( !array_key_exists($columnKey, $value)) {
trigger_error("Key \"$columnKey\" does not exist in array");
return false;
}
if (is_null($indexKey)) {
$array[] = $value[$columnKey];
}
else {
if ( !array_key_exists($indexKey, $value)) {
trigger_error("Key \"$indexKey\" does not exist in array");
return false;
}
if ( ! is_scalar($value[$indexKey])) {
trigger_error("Key \"$indexKey\" does not contain scalar value");
return false;
}
$array[$value[$indexKey]] = $value[$columnKey];
}
}
return $array;
}
}
Reference:

You can also use array_map() function if you haven't array_column() because of PHP<5.5:
Example:
$a = array(
array(
'id' => 2135,
'first_name' => 'John',
'last_name' => 'Doe',
),
array(
'id' => 3245,
'first_name' => 'Sally',
'last_name' => 'Smith',
)
);
array_column($a, 'last_name');
Becomes:
array_map(function($element) {
return $element['last_name'];
}, $a);
So it your case the code will be:
array_count_values(
array_map(function($arr) use ($idForBar) {
return $arr[$idForBar];
}, $queryResultArray)
);
This above is working on PHP 5.3.0 and above!
If you have < PHP 5.3.0, as you wrote PHP 5.2.17, just use simple function:
function get_field_data($array, $field, $idField = null) {
$_out = array();
if (is_array($array)) {
if ($idField == null) {
foreach ($array as $value) {
$_out[] = $value[$field];
}
}
else {
foreach ($array as $value) {
$_out[$value[$idField]] = $value[$field];
}
}
return $_out;
}
else {
return false;
}
}
And the usage:
$output = get_field_data($queryResultArray, $idForBar);

You can also use the alternative code of array_column(), it's simple just paste below line and replace your variable.
Code:
array_map(function($element){return $element['last_name'];}, $a);

Using array_map() instead, something like:
array_count_values(
array_map(
function($value) use ($idForBar) {
return $value[$idForBar];
},
json_decode(
json_encode($queryResultArray),
true
)
)
);

You can always use another implementation of function array_column
if (!function_exists('array_column')) {
function array_column(array $array, $columnKey, $indexKey = null)
{
$result = array();
foreach ($array as $subArray) {
if (!is_array($subArray)) {
continue;
} elseif (is_null($indexKey) && array_key_exists($columnKey, $subArray)) {
$result[] = $subArray[$columnKey];
} elseif (array_key_exists($indexKey, $subArray)) {
if (is_null($columnKey)) {
$result[$subArray[$indexKey]] = $subArray;
} elseif (array_key_exists($columnKey, $subArray)) {
$result[$subArray[$indexKey]] = $subArray[$columnKey];
}
}
}
return $result;
}
}

There is an official recommendation for PHP versions that don't support array_colum() under the "see also" section:
» Recommended userland implementation for PHP lower than 5.5
Their recommendation is another if (!function_exists('array_column')) approach, but the code is actually extracted from the array_column library and is a little more generalized than the examples on this page.

Related

Search inside multidimensional array and return other key value

I have the following
Multidimensional array.
What I'm trying to do is to search for an IDITEM value and if it's found, return the value of the "PRECO" key.
I'm using the following function to check if the value exists and it works fine, but I can't find a way to get the "PRECO" value of the found IDITEM.
Function:
function search_array($needle, $haystack) {
if(in_array($needle, $haystack)) {
return true;
}
foreach($haystack as $element) {
if(is_array($element) && search_array($needle, $element))
return true;
}
return false;
}
Anyone can help me with that?
You can change the first if statement to return it instead of returning a boolean :
function search_array($needle, $haystack) {
if(in_array($needle, $haystack) && array_key_exists('PRECO', $haystack)) {
return $haystack['PRECO'];
}
foreach($haystack as $element) {
if(is_array($element))
{
$result = search_array($needle, $element);
if($result !== false)
return $result;
}
}
return false;
}
The easiest idea I can remember is converting that boolean search_array into a path creator, where it will return the path for the item, or false if it isn't found.
function get_array_path_to_needle($needle, array $haystack)
{
if(in_array($needle, $haystack))
{
return true;
}
foreach($haystack as $key => $element)
{
if(is_array($element) && ($path = get_array_path_to_needle($needle, $element)) !== false)
{
return $path === true ? $key : $key . '.' . $path;
}
}
return false;
}
Then, since you already have the path, then rerun the array to fetch the item
function get_array_value_from_path(array $path, array $haystack)
{
$current = $haystack;
foreach($path as $key)
{
if(is_array($current) && array_key_exists($key, $current))
{
$current = $current[$key];
}
else
{
return false;
}
}
return $current;
}
This wont get you the PRECO, but it will return the item (array) where id found the value you searched for.
So a simple usage would be:
$path = get_array_path_to_needle('000000000000001650', $data);
$item = get_array_value_from_path(explode('.', $path), $data);
// here you have full array for that item found
print_r($item);
// here you have your price
print_r($item['PRECO']);
Use a static variable to remember the status between multiple function calls, and also to store the desired PRECO value. It makes the function remember the value of the given variable ($needle_value in this example) between multiple calls.
So your search_array() function should be like this:
function search_array($needle, $haystack){
static $needle_value = null;
if($needle_value != null){
return $needle_value;
}
foreach($haystack as $key => $value){
if(is_array($value)){
search_array($needle, $value);
}else if($needle == $value){
$needle_value = $haystack['PRECO'];
break;
}
}
return $needle_value;
}
This function will finally return $needle_value, which is your desired PRECO value from the haystack.
The simplest way is to use a foreach loop twice. Check for the key and store the result into an array for later use.
Based on your array, the below
$search = '000000000000001650';
foreach($array as $element){
foreach ($element['ITEM'] as $item){
if (isset($item['IDITEM']) and $item['IDITEM'] == $search){
$results[] = $item['PRECO'];
}
}
}
print_r($results);
Will output
Array
(
[0] => 375
)
Here is the simple example with array:
// your array with two indexes
$yourArr = array(
0=>array(
'IDDEPARTAMENTO'=>'0000000001',
'DESCRDEPT'=>'Área',
'ITEM'=>
array(
array(
'SETID'=>'RX',
'IDITEM'=>'000000000000001367',
'DESCRITEM'=>'PISTA TESTE DRIV',
'PRECO'=>'1338.78'),
array(
'SETID'=>'RX',
'IDITEM'=>'000000000000001925',
'DESCRITEM'=>'PISTA TESTE DRIV2',
'PRECO'=>'916'),
)
),
1=>array(
'IDDEPARTAMENTO'=>'0000000010',
'DESCRDEPT'=>'Merch',
'ITEM'=>
array(
array(
'SETID'=>'RX',
'IDITEM'=>'000000000000002036',
'DESCRITEM'=>'PISTA TESTE DRIV23',
'PRECO'=>'200.78'),
array(
'SETID'=>'RX',
'IDITEM'=>'000000000000001608',
'DESCRITEM'=>'PISTA CRACHÁ DRIV4',
'PRECO'=>'44341'),
)
));
// solution
$newArr = array();
foreach ($yourArr as $value) {
foreach ($value as $key => $innerVal) {
if($key == 'ITEM'){
foreach ($innerVal as $key_inner => $keyinner) {
if(!empty($keyinner['IDITEM'])){
$newArr[$keyinner['IDITEM']] = $keyinner['PRECO'];
}
}
}
}
}
echo "<pre>";
print_r($newArr);
Result values with IDITEM:
Array
(
[000000000000001367] => 1338.78
[000000000000001925] => 916
[000000000000002036] => 200.78
[000000000000001608] => 44341
)

Search a number in string formatted array in PHP?

My array looks like this:
array( '0|500|0.50', '501|1000|0.75' );
I am trying to run a search to get the KEY which has the searched value.
I made this function to search:
function cu_array_search($str,$array){
foreach($array as $key => $value) {
if(strstr($str,$value)) {
return true;
} else {
return false;
}
}
}
and using it like this when checking:
if (cu_array_search(500,$array) {
but it never return true, despite that 500 exists in first key in array .
How to resolve this?
Thanks
strpos will make you function return true even that's 0.5001 but not 500.
You should explode the value by |, then check whether the number in the array.
function cu_array_search($num, $array){
return count(array_filter($array, function ($var) use ($num) {
return in_array($num, explode('|', $var));
})) > 0;
}
The haystack is the first argument, not the second:
if(strstr($value,$str)) {
Additionally, strpos is faster at this, so you should use:
function cu_array_search($str,$array){
foreach($array as $key => $value) {
if(strpos($value,$str) !== false) {
return $key;
} else {
return false;
}
}
}
First, strstr parameters are wrong
Second, return false should be at the end of the loop.
Third, If you need KEY then You need to use return $key instead of return true
function cu_array_search($str,$array){
foreach($array as $key => $value) {
if(strstr($value, $str)) {
return $key;
}
}
return false;
}
This works fine
<?php
function cu_array_search($str, $array) {
foreach($array as $key => $value) {
$temp_array=explode('|', $value);
if (in_array($str, $temp_array))
return true;
}
return false;
}
$array = array( '0|500|0.50', '501|1000|0.75' );
if (cu_array_search(500, $array))
echo "success";
else
echo "failed" ;
?>

generic function for extracting values from an array with one particular key in PHP

Is it possible in PHP to extract values from an array with a particular key path and return an array of those values? I'll explain with an example:
$user =
array (
array(
'id' => 1,
'email' =>'asd#example.com',
'project' => array ('project_id' => 222, 'project_name' => 'design')
),
array(
'id' => 2,
'email' =>'asd2#example.com',
'project' => array ('project_id' => 333, 'project_name' => 'design')
)
);
/** I have to write a function something like: */
$projectIds = extractValuesWithKey($user, array('project', 'project_id'));
print_r($projectIds);
Output:
Array(
[0] => 222,
[1] => 333
)
I would have gone for a different approach (not that there's anything wrong with the array-function-based answers) by using a recursive iterator to flatten the array which makes the key-path comparison fairly simple.
function extractValuesWithKey($array, $keys) {
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
$keys_count = count($keys);
// No point going deeper than we have to!
$iterator->setMaxDepth($keys_count);
$result = array();
foreach ($iterator as $value) {
// Skip any level that can never match our keys
if ($iterator->getDepth() !== $keys_count) {
continue;
}
// Build key path to current item for comparison
$key_path = array();
for ($depth = 1; $depth <= $keys_count; $depth++) {
$key_path[] = $iterator->getSubIterator($depth)->key();
}
// If key paths match, add to results
if ($key_path === $keys) {
$result[] = $value;
}
}
return $result;
}
To make the whole thing more useful, you could even wrap the code into a custom FilterIterator rather than a basic function, but I guess that's probably a different question entirely.
Well, that's easier than you think.
function extractValuesWithKey($array, $parts) {
$return = array();
$rawParts = $parts;
foreach ($array as $value) {
$tmp = $value;
$found = true;
foreach ($parts as $key) {
if (!is_array($tmp) || !isset($tmp[$key])) {
$found = false;
continue;
} else {
$tmp = $tmp[$key];
}
}
if ($found) {
$return[] = $tmp;
}
}
return $return;
}
If the 'key path' isn't dynamic, you can do a one-liner with array_map:
$projectIds = array_map(function($arr) { return $arr['project']['project_id']; }, $user);
Alternatively, for dynamic paths:
function extractValuesWithKey($users, $path) {
return array_map(function($array) use ($path) {
array_walk($path, function($key) use (&$array) { $array = $array[$key]; });
return $array;
}, $users);
}
The closures/anonymous functions only work with PHP 5.3+, and I've no idea how this would compare performance-wise to a double foreach loop. Note also that there's no error checking to ensure that the path exists.
I also used a similiar function in one of my projects, maybe you find this useful:
function extractValuesWithKey($data, $path) {
if(!count($path)) return false;
$currentPathKey = $path[0];
if(isset($data[$currentPathKey])) {
$value = $data[$currentPathKey];
return is_array($value) ? extractValuesWithKey($value, array_slice($path, 1)) : $value;
}
else {
$tmp = array();
foreach($data as $key => $value) {
if(is_array($value)) $tmp[] = extractValuesWithKey($value, $path);
}
return $tmp;
}
}

access php array children through parameters?

I have a unique case where I have an array like so:
$a = array('a' => array('b' => array('c' => 'woohoo!')));
I want to access values of the array in a manner like this:
some_function($a, array('a')) which would return the array for position a
some_function($a, array('a', 'b', 'c')) which would return the word 'woohoo'
So basically, it drills down in the array using the passed in variables in the second param and checks for the existence of that key in the result. Any ideas on some native php functions that can help do this? I'm assuming it'll need to make use of recursion. Any thoughts would be really appreciated.
Thanks.
This is untested but you shouldn't need recursion to handle this case:
function getValueByKey($array, $key) {
foreach ($key as $val) {
if (!empty($array[$val])) {
$array = $array[$val];
} else return false;
}
return $array;
}
You could try with RecursiveArrayIterator
Here is an example on how to use it.
Here’s a recursive implementation:
function some_function($array, $path) {
if (!count($path)) {
return;
}
$key = array_shift($path);
if (!array_key_exists($key, $array)) {
return;
}
if (count($path) > 1) {
return some_function($array[$key], $path);
} else {
return $array[$key];
}
}
And an iterative implementation:
function some_function($array, $path) {
if (!count($path)) {
return;
}
$tmp = &$array;
foreach ($path as $key) {
if (!array_key_exists($key, $tmp)) {
return;
}
$tmp = &$tmp[$key];
}
return $tmp;
}
These functions will return null if the path is not valid.
$a['a'] returns the array at position a.
$a['a']['b']['c'] returns woohoo.
Won't this do?

Access PHP array element with a function?

I'm working on a program that uses PHP's internal array pointers to iterate along a multidimensional array. I need to get an element from the current row, and I've been doing it like so:
$arr[key($arr)]['item']
However, I'd much prefer to use something like:
current($arr)['item'] // invalid syntax
I'm hoping there's a function out there that I've missed in my scan of the documentation that would enable me to access the element like so:
getvalue(current($arr), 'item')
or
current($arr)->getvalue('item')
Any suggestions?
I very much doubt there is such a function, but it's trivial to write
function getvalue($array, $key)
{
return $array[$key];
}
Edit: As of PHP 5.4, you can index array elements directly from function expressions, current($arr)['item'].
Have you tried using one of the iterator classes yet? There might be something in there that does exactly what you want. If not, you can likely get what you want by extending the ArrayObject class.
This function might be a bit lenghty but I use it all the time, specially in scenarious like:
if (array_key_exists('user', $_SESSION) === true)
{
if (array_key_exists('level', $_SESSION['user']) === true)
{
$value = $_SESSION['user']['level'];
}
else
{
$value = 'DEFAULT VALUE IF NOT EXISTS';
}
}
else
{
$value = 'DEFAULT VALUE IF NOT EXISTS';
}
Turns to this:
Value($_SESSION, array('user', 'level'), 'DEFAULT VALUE IF NOT EXISTS');
Here is the function:
function Value($array, $key = 0, $default = false)
{
if (is_array($array) === true)
{
if (is_array($key) === true)
{
foreach ($key as $value)
{
if (array_key_exists($value, $array) === true)
{
$array = $array[$value];
}
else
{
return $default;
}
}
return $array;
}
else if (array_key_exists($key, $array) === true)
{
return $array[$key];
}
}
return $default;
}
PS: You can also use unidimensional arrays, like this:
Value($_SERVER, 'REQUEST_METHOD', 'DEFAULT VALUE IF NOT EXISTS');
If this does not work, how is your multidimensional array composed? A var_dump() might help.
$subkey = 'B';
$arr = array(
$subkey => array(
'AB' => 'A1',
'AC' => 'A2'
)
);
echo current($arr[$subkey]);
next($arr[$subkey]);
echo current($arr[$subkey]);
I often use
foreach ($arr as $key=>$val) {
$val['item'] /*$val is the value of the array*/
$key /*$key is the key used */
}
instead of
next($arr)/current($arr)

Categories