This question already has answers here:
How to check if PHP array is associative or sequential?
(60 answers)
Closed 9 years ago.
How do I find out if a PHP array was built like this:
array('First', 'Second', 'Third');
Or like this:
array('first' => 'First', 'second' => 'Second', 'third' => 'Third');
???
I have these simple functions in my handy bag o' PHP tools:
function is_flat_array($ar) {
if (!is_array($ar))
return false;
$keys = array_keys($ar);
return array_keys($keys) === $keys;
}
function is_hash($ar) {
if (!is_array($ar))
return false;
$keys = array_keys($ar);
return array_keys($keys) !== $keys;
}
I've never tested its performance on large arrays. I mostly use it on arrays with 10 or fewer keys so it's not usually an issue. I suspect it will have better performance than comparing $keys to the generated range 0..count($array).
print_r($array);
There is no difference between
array('First', 'Second', 'Third');
and
array(0 => 'First', 1 => 'Second', 2 => 'Third');
The former just has implicit keys rather than you specifying them
programmatically, you can't. I suppose the only way to check in a case like yours would be to do something like:
foreach ($myarray as $key => $value) {
if ( is_numeric($key) ) {
echo "the array appears to use numeric (probably a case of the first)";
}
}
but this wouldn't detect the case where the array was built as $array = array(0 => "first", 1 => "second", etc);
function is_assoc($array) {
return (is_array($array)
&& (0 !== count(array_diff_key($array, array_keys(array_keys($array))))
|| count($array)==0)); // empty array is also associative
}
here's another
function is_assoc($array) {
if ( is_array($array) && ! empty($array) ) {
for ( $i = count($array) - 1; $i; $i-- ) {
if ( ! array_key_exists($i, $array) ) { return true; }
}
return ! array_key_exists(0, $array);
}
return false;
}
Gleefully swiped from the is_array comments on the PHP documentation site.
That's a little tricky, especially that this form array('First', 'Second', 'Third'); implicitly lets PHP generate keys values.
I guess a valid workaround would go something like:
function array_indexed( $array )
{
$last_k = -1;
foreach( $array as $k => $v )
{
if( $k != $last_k + 1 )
{
return false;
}
$last_k++;
}
return true;
}
If you have php > 5.1 and are only looking for 0-based arrays, you can shrink the code to
$stringKeys = array_diff_key($a, array_values($a));
$isZeroBased = empty($stringKeys);
I Hope this will help you
Jerome WAGNER
function isAssoc($arr)
{
return $arr !== array_values($arr);
}
Related
There is an array of airports that gets filled with a user list.
$airport_array[$airport_row['airportICAO']] = array(
'airportName' => $airport_row['airportName'],
'airportCity' => $airport_row['airportCity'],
'airportLat' => $airport_row['airportLat'],
'airportLong' => $airport_row['airportLong'],
'airportUserCount' => 0,
'airportUserList' => array()
);
After filling, "airportUserCount" will either be 0 or higher than 1. Now, I want to remove all airports from the array where airportUserCount is set to 0. What is the most performant way to do it? I thought about a foreach loop but I fear it's not necessarily the most elegant solution.
Use this code
foreach($airport_array as $key=>$value){
if($value['airportUserCount']==0){
unset($airport_array[$key]);
}
}
Here is live demo : https://eval.in/608462
$new_airports = array_filter(
$old_airports,
function($a) { return 0 < $a['airportUserCount']; }
);
foreach loop, check for the ones that have the Count == 0 then remove them from the array.
$result = array();
foreach ($airport_array[$airport_row['airportICAO']] as $arrays)
{
if($arrays['airportUserCount'] == 0) {
array_push($result, $arrays);
}
}
Use array_filter:
$a = array_filter($a, function($v) { return $v['airportUserCount'] != 0; });
Demo :- https://eval.in/608464
array_filter allows you to iterate through an array while using a callback function to check values.
function filterAirports($airports){
return ($airport['airportUserCount'] == 0) ? true : false ;
}
print_r(array_filter($airport_array, "filterAirports"));
I`m using $_POST array with results of checkbox's selected from a form.
I'm thinking of using php in_array function but how could I extract only values that start with chk Given the following array:
Array (
[chk0] => 23934567622639616
[chk3] => 23934567622639618
[chk4] => 23934567622639619
[select-all] => on
[process] => Process
)
Thanks!
Simple and fast
$result=array();
foreach($_POST as $key => $value){
if(substr($key, 0, 2) == 'chk'){
$result[$key] = $value;
}
}
Lots of ways to do this, I like array_filter.
Example:
$result = array_filter(
$_POST,
function ($key) {
return strpos($key, "chk") === 0;
},
ARRAY_FILTER_USE_KEY
);
Here's a solution from http://php.net/manual/en/function.preg-grep.php
<?php
function preg_grep_keys($pattern, $input, $flags = 0) {
return array_intersect_key($input, array_flip(preg_grep($pattern, array_keys($input), $flags)));
}
?>
I would use array_filter
$ary = array_filter($originalArray,
function($key){ return preg_match('/chk/', $key); },
ARRAY_FILTER_USE_KEY
);
This question already has answers here:
array_key_exists is not working
(4 answers)
Closed 8 years ago.
I have a matrix¹²³ with the following structure (it's dynamic, may or may not contains those keys (or even more))
array(
"where" => array(
"data_col1": "val1",
"data_col2": "val2"
),
"like" => array(
"data_col3": "val3"
)
);
What I need to do is to find if $var_with_data_col_name exists or not.
Using array_key_exists I can check if "where" or "like" exist, but I couldn't find a way to check inside them for a specific key.
PS:
$var_with_data_col_name would be a variable with one of the following strings:
- data_col1
- data_col2
- data_col3
You can't search for array keys or values in multidimensional arrays directly. Walk through the array and search for it then.
$data_column_1_exists = false;
foreach($array as $key => $value)
{
if(array_key_exists('data_col1', $value)
&& $key == 'where' //optionally check in specific array
)
{
$data_column_1_exists = true;
}
}
You can use this -
function key_exists_level2($arr, $key){
foreach($arr as $level1arr){
if(isset($level1arr[$key])){
return true;
}
}
return false;
}
//And check with
key_exists_level2($arr, $var_with_data_col_name)
Itterate through the "main array" and use the same function for checking the keys of each "sub array"
You can use this code, which gives you the key..which has your $var_with_data_col_name .
$data = array(
"where" => array(
"data_col1" => "val1",
"data_col2" => "val2"
),
"like" => array(
"data_col3" => "val3"
)
);
$key;
$flag = false;
$data_key = 'data_col1';
foreach($data as $our_key => $array){
if(array_key_exists($data_key,$array)){
$key = $our_key;
$flag = true;
}
}
if($flag){
print_r($data[$key]);
}
I'm sure there is already a function out there, more of an exercise for myself!
function recursive_array_key_exists($needle, array $haystack) {
if (array_key_exists($needle, $haystack)) return true;
foreach($haystack as $value) {
if (is_array($value)) {
if (recursive_array_key_exists($needle, $value)) return true;
}
}
return false;
}
Just saw the comment linking to this answer: array_key_exists is not working
I guess mine is basically identical just less code!
Ok I have this kind of associative array in PHP
$arr = array(
"fruit_aac" => "apple",
"fruit_2de" => "banana",
"fruit_ade" => "grapes",
"other_add" => "sugar",
"other_nut" => "coconut",
);
now what I want is to select only the elements that starts with key fruit_. How can be this possible? can I use a regex? or any PHP array functions available? Is there any workaround? Please give some examples for your solutions
$fruits = array();
foreach ($arr as $key => $value) {
if (strpos($key, 'fruit_') === 0) {
$fruits[$key] = $value;
}
}
One solution is as follows:
foreach($arr as $key => $value){
if(strpos($key, "fruit_") === 0) {
...
...
}
}
The === ensures that the string was found at position 0, since strpos can also return FALSE if string was not found.
You try it:
function filter($var) {
return strpos($var, 'fruit_') !== false;
}
$arr = array(
"fruit_aac"=>"apple",
"fruit_2de"=>"banana",
"fruit_ade"=>"grapes",
"other_add"=>"sugar",
"other_nut"=>"coconut",
);
print_r(array_flip(array_filter(array_flip($arr), 'filter')));
If you want to try regular expression then you can try code given below...
$arr = array("fruit_aac"=>"apple",
"fruit_2de"=>"banana",
"fruit_ade"=>"grapes",
"other_add"=>"sugar",
"other_nut"=>"coconut",
);
$arr2 = array();
foreach($arr AS $index=>$array){
if(preg_match("/^fruit_.*/", $index)){
$arr2[$index] = $array;
}
}
print_r($arr2);
I hope it will be helpful for you.
thanks
Example:
$arr = array(1 => 'Foo', 5 => 'Bar', 6 => 'Foobar');
/*... do some function so $arr now equals:
array(0 => 'Foo', 1 => 'Bar', 2 => 'Foobar');
*/
Use array_values($arr). That will return a regular array of all the values (indexed numerically).
PHP docs for array_values
array_values($arr);
To add to the other answers, array_values() will not preserve string keys. If your array has a mix of string keys and numeric keys (which is probably an indication of bad design, but may happen nonetheless), you can use a function like:
function reset_numeric_keys($array = array(), $recurse = false) {
$returnArray = array();
foreach($array as $key => $value) {
if($recurse && is_array($value)) {
$value = reset_numeric_keys($value, true);
}
if(gettype($key) == 'integer') {
$returnArray[] = $value;
} else {
$returnArray[$key] = $value;
}
}
return $returnArray;
}
Not that I know of, you might have already checked functions here
but I can imagine writing a simple function myself
resetarray($oldarray)
{
for(int $i=0;$i<$oldarray.count;$i++)
$newarray.push(i,$oldarray[i])
return $newarray;
}
I am little edgy on syntax but I guess u got the idea.