Considering array like:
$arr = array(
'key' => 'foo'
'key2' => 'bar',
0 => 'num_foo',
1 => 'num_bar'
);
How to extract values under 0 & 1? (Besides using for loop). Maybe any standard function do the job?
If you’re using a PHP version >= 5.6, you can use array_filter, with the flag that tells it to pass the key to the callback function.
$arr = array(
'key' => 'foo',
'key2' => 'bar',
0 => 'num_foo',
1 => 'num_bar'
);
$new_array = array_filter($arr, function($key) {
return is_numeric($key);
}, ARRAY_FILTER_USE_KEY);
var_dump($new_array);
https://3v4l.org/qfar9
Edit: As Robbie pointed out, using is_numeric is the better choice here. (Previously my example used is_int.)
Edit 2: Perhaps is_int is actually the better choice here. is_numeric would return true for values such as +0123.45e6, or hexadecimal/binary number notations as well – not sure if that’s desired.
is_int would normally return false for a value such as '1'. It works here, because we are dealing with arrays – and PHP automatically converts array keys to integer, if they are an “integer string.”
you can use array_filter() to return the numeric keys
// $Your_array is your original array with numeric and string keys
// array_filter() returns an array of the numeric keys
$numerickeys = array_filter(array_keys($Your_array), function($k) {return is_int($k);});
// this is a simple case where the filter function is a plain
// built-in function requiring one argument, it can be passed as a string:
// Really, this is all that's needed:
$numerickeys = array_filter(array_keys($Your_array), 'is_int');
If you use is_int() inside a foreach loop it's easy enough. Try this:
foreach ($arr as $key => $value) {
if (is_int($key)) {
echo "Found integer key with value: $value\n";
}
}
If you desperately want to avoid using a loop, try this:
array_walk($arr, function($val, $key) {
if (is_int($key)) {
echo "Found integer key with value: $val\n";
}
});
That does, of course, use a loop internally anyway.
Related
I have such code
<?php
$array =
[
['key_name' => 'Amazon Inc.', 'key_code' => '102923'],
['key_name' => 'Google inc, co io', 'key_code' =>'283923'],
['key_name' => 'IMSFT dcs', 'key_code' => '3384823'],
['key_name' => 'MSFTSurfshark io', 'key_code' =>'4473873']
];
$search_text = 'mSfT';
$lowText = strtolower($search_text); // to lower
$lowArr = array_walk_recursive($array, function (&$v) {$v = mb_strtolower(trim($v));}); // need convert to lower case whole array
print_r($lowArr); // here is empty
$r = array_filter($lowArr, function($el) use ($lowText) {return ( strpos($el['key_name'], $lowText) !== false );
});
$keys = array_keys($r); // all keys founded
print_r( $r[$keys[0]]['key_code']); //return only first match
?>
When i want convert array to lower case
$lowArr = array_walk_recursive($array, function ($v) {$v = mb_strtolower(trim($v));});
then script return nothing using https://www.w3schools.com/php/phptryit.asp?filename=tryphp_intro
Goals is to find arrays elemnt by it key_name and return this element key_code
Why this happens?
If i use $array = array_column($array, 'key_name', 'key_code'); how should look like php syntax for same things?
Note this note in the manual.
If callback needs to be working with the actual values of the array, specify the first parameter of callback as a reference. Then, any changes made to those elements will be made in the original array itself.
So you need declare the parameter as a reference in order to make changes to the original array.
function (&$v) {$v = mb_strtolower(trim($v));}
I'm currently using array_map to apply callbacks to elements of an array. But I want to be able to pass an argument to the callback function like array_walk does.
I suppose I could just use array_walk, but I need the return value to be an array like if you use array_map, not TRUE or FALSE.
So is it possible to use array_map and pass an argument to the callback function? Or perhaps make the array_walk return an array instead of boolean?
You don't need it to return an array.
Instead of:
$newArray = array_function_you_are_looking_for($oldArray, $funcName);
It's:
$newArray = $oldArray;
array_walk($newArray, $funcName);
If you want return value is an array, just use array_map. To add additional parameters to array_map use "use", ex:
array_map(function($v) use ($tmp) { return $v * $tmp; }, $array);
or
array_map(function($v) use ($a, $b) { return $a * $b; }, $array);
Depending on what kind of arguments you need to pass, you could create a wrapped function:
$arr = array(2, 4, 6, 8);
function mapper($val, $constant) {
return $val * $constant;
}
$constant = 3;
function wrapper($val) {
return mapper($val, $GLOBALS['constant']);
}
$arr = array_map('wrapper', $arr);
This actually seems too simple to be true. I suspect we'll need more context to really be able to help.
To expand a bit on Hieu's great answer, you can also use the $key => $value pairs of the original array. Here's an example with some code borrowed from comment section http://php.net/manual/en/function.array-map.php
The following will use 'use' and include an additional parameter which is a new array.
Below code will grab "b_value" and "d_value" and put into a new array $new_arr
(useless example to show a point)
// original array
$arr = ("a" => "b_value",
"c" => "d_value");
// new array
$new_arr = array();
array_map(function($k,$v) use (&$new_arr) { $new_arr[] = $v;}, array_keys($arr), $arr);
^ $k is key and $v is value
print_r of $new_arr is
Array
(
[0] => b_value
[1] => d_value
)
I have an array and in that array I have an array key that looks like, show_me_160 this array key may change a little, so sometimes the page may load and the array key maybe show_me_120, I want to now is possible to just string match the array key up until the last _ so that I can check what the value is after the last underscore?
one solution i can think of:
foreach($myarray as $key=>$value){
if("show_me_" == substr($key,0,8)){
$number = substr($key,strrpos($key,'_'));
// do whatever you need to with $number...
}
}
I ran into a similar problem recently. This is what I came up with:
$value = $my_array[current(preg_grep('/^show_me_/', array_keys($my_array)))];
you would have to iterate over your array to check each key separately, since you don't have the possibility to query the array directly (I'm assuming the array also holds totally unrelated keys, but you can skip the if part if that's not the case):
foreach($array as $k => $v)
{
if (strpos($k, 'show_me_') !== false)
{
$number = substr($k, strrpos($k, '_'));
}
}
However, this sounds like a very strange way of storing data, and if I were you, I'd check if there's not an other way (more efficient) of passing data around in your application ;)
to search for certain string in array keys you can use array_filter(); see docs
// the array you'll search in
$array = ["search_1"=>"value1","search_2"=>"value2","not_search"=>"value3"];
// filter the array and assign the returned array to variable
$foo = array_filter(
// the array you wanna search in
$array,
// callback function to search for certain sting
function ($key){
return(strpos($key,'search_') !== false);
},
// flag to let the array_filter(); know that you deal with array keys
ARRAY_FILTER_USE_KEY
);
// print out the returned array
print_r($foo);
if you search in the array values you can use the flag 0 or leave the flag empty
$foo = array_filter(
// the array you wanna search in
$array,
// callback function to search for certain sting
function ($value){
return(strpos($value,'value') !== false);
},
// flag to let the array_filter(); know that you deal with array value
0
);
or
$foo = array_filter(
// the array you wanna search in
$array,
// callback function to search for certain sting
function ($value){
return(strpos($value,'value') !== false);
}
);
if you search in the array values and array keys you can use the flag ARRAY_FILTER_USE_BOTH
$foo = array_filter(
// the array you wanna search in
$array,
// callback function to search for certain sting
function ($value, $key){
return(strpos($key,'search_') !== false or strpos($value,'value') !== false);
},
ARRAY_FILTER_USE_BOTH
);
in case you'll search for both you have to pass 2 arguments to the callback function
You can also use a preg_match based solution:
foreach($array as $str) {
if(preg_match('/^show_me_(\d+)$/',$str,$m)) {
echo "Array element ",$str," matched and number = ",$m[1],"\n";
}
}
filter_array($array,function ($var){return(strpos($var,'searched_word')!==FALSE);},);
return array 'searched_key' => 'value assigned to the key'
foreach($myarray as $key=>$value)
if(count(explode('show_me_',$event_key)) > 1){
//if array key contains show_me_
}
More information (example):
if array key contain 'show_me_'
$example = explode('show_me_','show_me_120');
print_r($example)
Array ( [0] => [1] => 120 )
print_r(count($example))
2
print_r($example[1])
120
I have an associative array and I need to find the numeric position of a key.
I could loop through the array manually to find it, but is there a better way build into PHP?
$a = array(
'blue' => 'nice',
'car' => 'fast',
'number' => 'none'
);
// echo (find numeric index of $a['car']); // output: 1
echo array_search("car",array_keys($a));
$blue_keys = array_search("blue", array_keys($a));
http://php.net/manual/en/function.array-keys.php
While Fosco's answer is not wrong there is a case to be considered with this one: mixed arrays. Imagine I have an array like this:
$a = array(
"nice",
"car" => "fast",
"none"
);
Now, PHP allows this kind of syntax but it has one problem: if I run Fosco's code I get 0 which is wrong for me, but why this happens?
Because when doing comparisons between strings and integers PHP converts strings to integers (and this is kinda stupid in my opinion), so when array_search() searches for the index it stops at the first one because apparently ("car" == 0) is true.
Setting array_search() to strict mode won't solve the problem because then array_search("0", array_keys($a)) would return false even if an element with index 0 exists.
So my solution just converts all indexes from array_keys() to strings and then compares them correctly:
echo array_search("car", array_map("strval", array_keys($a)));
Prints 1, which is correct.
EDIT:
As Shaun pointed out in the comment below, the same thing applies to the index value, if you happen to search for an int index like this:
$a = array(
"foo" => "bar",
"nice",
"car" => "fast",
"none"
);
$ind = 0;
echo array_search($ind, array_map("strval", array_keys($a)));
You will always get 0, which is wrong, so the solution would be to cast the index (if you use a variable) to a string like this:
$ind = 0;
echo array_search((string)$ind, array_map("strval", array_keys($a)));
The solution with array_search would be really heavy, and it's unnecessary to use straight search in this situation.
Much better solution would be:
$keyIndexOfWhichYouAreTryingToFind = 'c';
$array = [
'a' => 'b',
'c' => 'd'
];
$index = array_flip(array_keys($array))[$keyIndexOfWhichYouAreTryingToFind];
This type of search would have much better performance on big arrays.
$a = array(
'blue' => 'nice',
'car' => 'fast',
'number' => 'none'
);
var_dump(array_search('car', array_keys($a)));
var_dump(array_search('blue', array_keys($a)));
var_dump(array_search('number', array_keys($a)));
All solutions based on array_keys don't work for mixed arrays. Solution is simple:
echo array_search($needle,array_keys($haystack), true);
From php.net:
If the third parameter strict is set to TRUE then the array_search() function will search for identical elements in the haystack. This means it will also perform a strict type comparison of the needle in the haystack, and objects must be the same instance.
a solution i came up with... probably pretty inefficient in comparison tho Fosco's solution:
protected function getFirstPosition(array$array, $content, $key = true) {
$index = 0;
if ($key) {
foreach ($array as $key => $value) {
if ($key == $content) {
return $index;
}
$index++;
}
} else {
foreach ($array as $key => $value) {
if ($value == $content) {
return $index;
}
$index++;
}
}
}
Do I really have to do this to reset an array?
foreach ($array as $i => $value) {
unset($array[$i]);
}
EDIT:
This one makes more sense, as the previous one is equivalent to $array=array();
foreach ($array as $i => $value) {
$array[$i]=NULL;
}
$keys = array_keys($array);
$values = array_fill(0, count($keys), null);
$new_array = array_combine($keys, $values);
Get the Keys
Get an array of nulls with the same number of elements
Combine them, using keys and the keys, and the nulls as the values
As comments suggest, this is easy as of PHP 5.2 with array_fill_keys
$new_array = array_fill_keys(array_keys($array), null);
Fill array with old keys and null values
$array = array_fill_keys(array_keys($array), null)
There is no build-in function to reset an array to just it's keys.
An alternative would be via a callback and array_map():
$array = array( 'a' => 'foo', 'b' => 'bar', 'c' => 'baz' );
With regular callback function
function nullify() {}
$array = array_map('nullify', $array);
Or with a lambda with PHP < 5.3
$array = array_map(create_function('', ''), $array);
Or with lambda as of PHP 5.3
$array = array_map(function() {}, $array);
In all cases var_dump($array); outputs:
array(3) {
["a"]=> NULL
["b"]=> NULL
["c"]=> NULL
}
Define this function and call it whenever you need it:
function erase_val(&$myarr) {
$myarr = array_map(create_function('$n', 'return null;'), $myarr);
}
// It's call by reference so you don't need to assign your array to a variable.
// Just call the function upon it
erase_val($array);
That's all!
Get the array keys, then use them to create a new array with NULL values:
array_fill_keys(array_keys($array), NULL);
About array_fill_keys():
The array_fill_keys() function fills an array with values, specifying keys.
About array_keys():
The array_keys() function returns all the keys of an array.
foreach($a as &$v)
$v = null;
The reasoning behind setting an array item to null is that an array needs to have a value for each key, otherwise a key makes no sense. That is why it is called a key - it is used to access a value. A null value seems like a reasonable choice here.
Wrap it in a [reusable] procedure:
function array_purge_values(&$a) {
foreach($a as &$v)
$v = null;
}
Keep in mind though that PHP versions 5.3 and those released later, pass values to functions by reference by default, i.e. the ampersand preceding argument variable in the function declaration is redundant. Not only that, but you will get a warning that the notion is deprecated.
If you need to nullify the values of a associative array you can walk the whole array and make a callback to set values to null thus still having keys
array_walk($ar,function(&$item){$item = null;});
In case if you need to nullify the whole array just reassign it to empty one
$ar = array();
unset would delete the key, You need to set the value to null or 0 as per your requirement.
Example
I don't get the question quite well, but your example
foreach ($array as $i => $value) {
unset($array[$i]);
}
is equivilent to
$array = array();
Why not making an array with required keys and asinging it to variable when you want reset it?
function resetMyArr(&$arr)
{
$arr = array('key1'=>null,'key2'=>null);
}
This is a fairly old topic, but since I referenced to it before coming up with my own solution for a more specific result, so therefore I will share with you that solution.
The desired result was to nullify all values, while keeping keys, and for it to recursively search the array for sub-arrays as well.
RECURSIVELY SET MULTI-LEVEL ARRAY VALUES TO NULL:
function nullifyArray(&$arrayData) {
if (is_array($arrayData)) {
foreach ($arrayData as $aKey => &$aValue) {
if (is_array($aValue)) {
nullifyArray($aValue);
} else {
$aValue = null;
}
}
return true; // $arrayData IS an array, and has been processed.
} else {
return false; // $arrayData is NOT an array, no action(s) were performed.
}
}
And here is it in use, along with BEFORE and AFTER output of the array contents.
PHP code to create a multilevel-array, and call the nullifyArray() function:
// Create a multi-level array.
$testArray = array(
'rootKey1' => 'rootValue1',
'rootKey2' => 'rootValue2',
'rootArray1' => array(
'subKey1' => 'subValue1',
'subArray1' => array(
'subSubKey1' => 'subSubValue1',
'subSubKey2' => 'subSubValue2'
)
)
);
// Nullify the values.
nullifyArray($testArray);
BEFORE CALL TO nullifyArray():
Array
(
[rootKey1] => rootValue1
[rootKey2] => rootValue2
[rootArray1] => Array
(
[subKey1] => subValue1
[subArray1] => Array
(
[subSubKey1] => subSubValue1
[subSubKey2] => subSubValue2
)
)
)
AFTER CALL TO nullifyArray():
Array
(
[rootKey1] =>
[rootKey2] =>
[rootArray1] => Array
(
[subKey1] =>
[subArray1] => Array
(
[subSubKey1] =>
[subSubKey2] =>
)
)
)
I hope it helps someone/anyone, and Thank You to all who previously answered the question.
And speed test
This test shows speed when clearing a large array
$a1 = array();
for($i=0;$i<=1000;$i++)
{
$a1['a'.$i] = $i;
}
$b = $a1;
$start_time = microtime(TRUE);
foreach ($a1 as $field => $val) {
$a1[$field]=NULL;
}
$end_time = microtime(TRUE);
$duration = $end_time - $start_time;
var_dump( $duration*1000 );
var_dump('all emelent of array is '.reset($a1));
$start_time = microtime(TRUE);
$allkeys = array_keys($b);
$newarray = array_fill_keys($allkeys, null);
$end_time = microtime(TRUE);
$duration = $end_time - $start_time;
var_dump( $duration*1000 );
var_dump('all emelent of array is '.reset($newarray));
Just do this:
$arrayWithKeysOnly = array_keys($array);
http://php.net/manual/en/function.array-keys.php
EDIT: Addressing comment:
Ok, then do this:
$arrayWithKeysProper = array_flip(array_keys($array));
http://www.php.net/manual/en/function.array-flip.php
EDIT: Actually thinking about it, that probably won't work either.