How to filter deep array? - php

I have this array:
$test = [
['teams' => ['home' => 'Lazio']],
['teams' => ['away' => 'Inter']]
];
I need to search Inter, so I did:
$key = array_search('Inter', array_column($test, 'teams'));
var_dump($test[$key]);
but it returns false as $key.

array_search() doesn't search nested arrays. There's no built-in functionthat does this, so just use a loop.
$key == null;
foreach (array_column($test, 'teams') as $i => $teams) {
if (in_array('Inter', $teams)) {
$key = $i;
break;
}
}
if ($key !== null) {
var_dump($test[$key]);
}

$needle = array_flip(['Inter']);
$result = array_filter(array_column($test, 'teams'), function(array $item) use ($needle) {
return array_intersect_key(array_flip($item), $needle);
});
using $needle as an array (and as result array_intersect_key) just in case you need to find more than one value.
You can change array_intersect_key to isset and single $needle value (instead of array).
also, is better to avoid using the array_search, (also in_array) functions for big arrays because of their complexity of algorithm (eq low performance)

I'm bored. You can filter out non-matching items and then get the key.
You can search for it anywhere in the array without specifying home, away or other:
$key = key(array_filter($test, function($v) { return in_array('Inter', $v['teams']); }));
Not the preferred way, but if there is only home and away you can search using an array:
($key = array_search(['away' => 'Inter'], array_column($test, 'teams'))) ||
($key = array_search(['home' => 'Inter'], array_column($test, 'teams')));
Or with one array_column call:
($t = array_column($test, 'teams')) && ($key = array_search(['away' => 'Inter'], $t)) ||
($key = array_search(['home' => 'Inter'], $t));
All of the code above returns the key of the first match.

Related

remove value from array what the words is not fully match

How i can remove a value from array what is not fully match the letters.
Array code example:
$Array = array(
'Funny',
'funnY',
'Games',
);
How I can unset all values from this array what is 'funny'
I try via unset('funny'); but is not removing the values from array, is removed just if i have 'funny' on array but 'funnY' or 'Funny' not working
Maybe there is some sophisticated solution with array_intersect_key or something which could do this in one line but I assume this approach is more easily read:
function removeCaseInsensitive($array, $toRemove) {
$ret = [];
foreach ($array as $v) {
if (strtolower($v) != strtolower($toRemove))
$ret[] = $v;
}
return $ret;
}
This returns a new array that does not contain any case of $toRemove. If you want to keep the keys than you can do this:
function removeCaseInsensitive($array, $toRemove) {
$keep = [];
foreach ($array as $k => $v) {
if (strtolower($v) != strtolower($toRemove))
$keep[$k] = true;
}
return array_intersect_keys($array, $keep);
}
You can filter out those values with a loose filtering rule:
$array = array_filter($array, function($value) {
return strtolower($value) !== 'funny';
});

PHP array_key_exists key LIKE string, is it possible?

I've done a bunch of searching but can't figure this one out.
I have an array like this:
$array = array(cat => 0, dog => 1);
I have a string like this:
I like cats.
I want to see if the string matches any keys in the array. I try the following but obviously it doesn't work.
array_key_exists("I like cats", $array)
Assuming that I can get any random string at a given time, how can I do something like this?
Pseudo code:
array_key_exists("I like cats", *.$array.*)
//The value for cat is "0"
Note that I want to check if "cat" in any form exists. It can be cats, cathy, even random letter like vbncatnm. I am getting the array from a mysql database and I need to know which ID cat or dog is.
You can use a regex on keys. So, if any words of your string equal to the key, $found is true. You can save the $key in the variable if you want. preg_match function allows to test a regular expression.
$keys = array_keys($array);
$found = false;
foreach ($keys as $key) {
//If the key is found in your string, set $found to true
if (preg_match("/".$key."/", "I like cats")) {
$found = true;
}
}
EDIT :
As said in comment, strpos could be better! So using the same code, you can just replace preg_match:
$keys = array_keys($array);
$found = false;
foreach ($keys as $key) {
//If the key is found in your string, set $found to true
if (false !== strpos("I like cats", $key)) {
$found = true;
}
}
This should help you achieve what you're trying to do:
$array = array('cat' => 10, 'dog' => 1);
$findThis = 'I like cats';
$filteredArray = array_filter($array, function($key) use($string){
return strpos($string, $key) !== false;
}, ARRAY_FILTER_USE_KEY);
I find that using the array_filter function with a closure/anonymous function to be a much more elegant way than a foreach loop because it maintains one level of indentation.
You could do using a preg_match with the value not in array but in search criteria
if(preg_match('~(cat|dog)~', "I like cats")) {
echo 'ok';
}
or
$criteria = '~(cat|dog)~';
if (preg_match($criteria, "I like cats")) {
echo 'ok';
}
Otherwise you could use a foreach on your array
foreach($array as $key => $value ) {
$pos = strpos("I like cats", $key);
if ($pos > 0) {
echo $key . ' '. $value;
}
}

Removing array key from multidimensional Arrays php

I have this array
$cart= Array(
[0] => Array([id] => 15[price] => 400)
[1] => Array([id] => 12[price] => 400)
)
What i need is to remove array key based on some value, like this
$value = 15;
Value is 15 is just example i need to check array and remove if that value exist in ID?
array_filter is great for removing things you don't want from arrays.
$cart = array_filter($cart, function($x) { return $x['id'] != 15; });
If you want to use a variable to determine which id to remove rather than including it in the array_filter callback, you can use your variable in the function like this:
$value = 15;
$cart = array_filter($cart, function($x) use ($value) { return $x['id'] != $value; });
There are a lot of weird array functions in PHP, but many of these requests are solved with very simple foreach loops...
$value = 15;
foreach ($cart as $i => $v) {
if ($v['id'] == $value) {
unset($cart[$i]);
}
}
If $value is not in the array at all, nothing will happen. If $value is in the array, the entire index will be deleted (unset).
you can use:
foreach($array as $key => $item) {
if ($item['id'] === $value) {
unset($array[$key]);
}
}

PHP Array Search & Add?

I have an array generated by PHP
array(
array(
'name'=>'node1',
'id' => '4'
),
array(
'name'=>'node2'
'id'=>'7'
)
)
And I am trying to add an array to a specific id (so let's say id 4)
'children'=>
array(
array('name'=>'node2','id'=>'5'),
array('name'=>'node3','id'=>'6')
)
So then it would look like
array(
array(
'name'=>'node1',
'id' => '4'
'children'=>
array(
array('name'=>'node2','id'=>'5'),
array('name'=>'node3','id'=>'6')
)
),
array(
'name'=>'node2'
'id'=>'7'
)
)
but I can't seem to figure out a way to search a multidimensional array, and add a multidimensional array to that array.
Any help?
Use a foreach loop to iterate through the array (making sure to get the key too), check the value, add if needed and break when found.
foreach($array as $k=>$v) {
if( $v['id'] == 4) {
$array[$k]['children'] = array(...);
break;
}
}
foreach($a as $k => $v)
{
if(is_array($v))
{
foreach($v as $ke => $va)
{
if($ke == 'children')
{
......
}
}
}
}
It's a monstrosity but it does what you want. Using push in a recursive function fails because the reference is destroyed after the second function call, so if you don't know how deep the key is there's a choice between using an arbitrary number of loops and hoping for the best, importing variables and using eval to push new values, or pulling apart and rebuilding the array. I chose eval. The description of what you wanted is a little different from pushing a value because you're looking for a key-value pair within an array, not an array. This function finds the key value pair and adds whatever you want as a sibling, if no value is specified the value is added as sibling to the first key matched. If no pushval is specified it will return the chain of keys that points to the matched key/key-value.
$ref_array is the multi-array to be modified,
$key is the key you're looking for,
$val is the value of the key you're looking for,
$newkey is the new key that will reference the new value,
$pushval is the new value to be indexed by $newkey.
DON'T pass an argument for the $val_array parameter. It's for use with recusive calls only. It's how the function distinguishes new calls from recursive calls, and it's how the function finds the key-value without disrupting the pass-by-reference.
function deepPush(&$ref_array, $key, $val=null, $newkey=null, $pushval=null, $val_array=null)
{
static $r, $keys;
#reset static vars on first call
if(!$val_array){ $r = 0; $keys = array();}
#cap recursion
if($r > 100){ trigger_error('Stack exceeded 100'); return;}
#init val_array
$val_array = ($r) ? $val_array : $ref_array;
#specified search value???
$search_val = ($val!==null && !in_array($val, $val_array)) ? true : false;
if(!array_key_exists($key, $val_array) || $search_val) {
$i=0;foreach($val_array as $k=>$v){
if(gettype($v) == 'array') {
if($i>0){/*dead-end*/array_pop($keys); /*keep recusion accurate*/$r-=$i;}
$keys[] = $k;/*build keychain*/
$r++; $i++; /*increment recursion, iteration*/
if(deepPush($ref_array, $key, $val, $newkey, $pushval, $v)){ /*close stack on 1st success*/return $keys;}
}//if
}//foreach
}//if
else{
if($pushval === null){return $keys;}
#add $newkey to the keychain
$keys[] = $newkey;
#process $pushval based on type
$pushval = (gettype($pushval) == 'string') ? sprintf("'%s'", $pushval) : var_export($pushval, true);
#link keys together to form pointer
$p = '$ref_array';
for($j=0,$c=count($keys); $j<$c; $j++) {
$k = $keys[$j];
$p .= "['$k']";
}//for
#concat the value to be pushed
$p .= sprintf("= %s;",$pushval);
#push it
eval($p);
$keys = array();
return true;
}//else
}
deepPush($array, 'id', 4, 'children', $addThis);

PHP Search Multidimensional Array - Not Associative

I am trying to write a piece of code that searches one column of 2-D array values and returns the key when it finds it. Right now I have two functions, one to find a value and return a boolean true or false and another (not working) to return the key. I would like to merge the two in the sense of preserving the recursive nature of the finding function but returning a key. I cannot think how to do both in one function, but working key finder would be much appreciated.
Thanks
function in_array_r($needle, $haystack, $strict = true) {
foreach ($haystack as $item) {
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && in_array_r($needle, $item, $strict))) {
return true;
}
}
return false;
}
function loopAndFind($array, $index, $search){
$returnArray = array();
foreach($array as $k=>$v){
if($v[$index] == $search){
$returnArray[] = $k;
}
}
return $returnArray;
}`
Sorry, I meant to add an example. For instance:
Array [0]{
[0]=hello
[1]=6
}
[1]
{
[0]=world
[1]=4
}
and I want to search the array by the [x][0] index to check each string of words for the search term. If found, it should give back the index/key in the main array like "world" returns 1
This works:
$array = array(array('hello', 6), array('world', 4));
$searchTerm = 'world';
foreach ($array as $childKey => $childArray) {
if ($childArray['0'] == $searchTerm) {
echo $childKey; //Your Result
}
}
You already have all you need in your first function. PHP does the rest:
$findings = array_map('in_array_r', $haystack);
$findings = array_filter($findings); # remove all not found
var_dump(array_keys($findings)); # the keys you look for

Categories