In array returning the wrong result - php

I have the below array..
<?php $arrLayout = array(
"section1" => array(
"wComingEpisodes" => array(
"title" => "Coming Episodes",
"display" => ""
)
));
?>
Then I want to check if wComingEpisodes is in the array so..
<?php if (in_array( "wComingEpisodes" , $arrLayout )) {
echo "CHECKED";}
?>
However its returning nothing even though it is in the array. Do I need to do something different because of the multiple arrays or where is my mistake?

in_array tests for values, not keys. It also does not test nested values.
$arrLayout = array(
"section1" => array(
"wComingEpisodes" => array(
"title" => "Coming Episodes",
"display" => ""
)
));
echo array_key_exists(
"wComingEpisodes",
// this is the array you're actually looking for
$arrLayout['section1'] )?'exists':'does not exist';

you're getting the correct result according to the documentation.
if you want to search an multidimensional array recursive, take a look at the user contributed notes, where you can find examples like this, that show how to do a recursive search (which seems to be what you're looking for).
EDIT:
i just noticed you're trying to find out if a specific key exists: in this case, you'll have to use array_key_exists (like in_array, this also doesn't do a recursive search, so you'll have to do something like this).

in array searches array values.
the string, "wComingEpisodes", is the key of the value
you may want to try using array_key_exists()

In_array isn't recursive by nature so it will only compare the value you give it with the first level of array items of the array you give it.
Thankfully you're not the first with the problem so heres a function that should help you out. Taken from php.net in_array documentation
function in_arrayr($needle, $haystack) {
foreach ($haystack as $v) {
if ($needle == $v) return true;
elseif (is_array($v)) return in_arrayr($needle, $v);
}
return false;
}
http://www.php.net/manual/en/function.in-array.php#60696

Related

How to find the desired element in the array and check whether it has a value or not?

I have a big array like this:
"twitter_link" => "http://twitter.com"
"twitter_text" => "text"
"youtube_link" => ""
"youtube_text" => ""
"snapchat_link" => "http://twitter.com"
"snapchat_text" => "text"
"linkedin_link" => ""
"linkedin_text" => ""
In this array, I need to find all all *_link keys and check if the value is set, then add all the keys where there is a value to another array
I would like to recommend you to read the following docs: https://laravel.com/docs/8.x/collections#available-methods, this may help you to find a multiple ways to iterate and alter an array if you don't think the array_* methods from php are enough for your needs! :D
Answering your question, what you need here is the knowledge of:
preg_match(...) function
array_filter(...) function using the flag: ARRAY_FILTER_USE_BOTH
You simply have to do the following:
$result = array_filter($links, fn($v, $k) => ($v !== "" && preg_match("/(_link)+$/i", $k)), ARRAY_FILTER_USE_BOTH)
And voilá, but what's the explanation? Simply...
Filter will use key and value for filtering by passing the flag ARRAY_FILTER_USE_BOTH as third element on array_filter() method.
On the filtering process, the $v (or value) shouldn't be empty.
Also on the filtering process, the $k (or key) should have a _filter at the end of the string.

Find which keys of separate arrays intersect using a function

Ok so I have two arrays, one is an input array full of data like :
$array1 = ["_token" => "62d46d4h6dfh841df8h", "sku62" => "3e", "name62" => "meh", "sku61" => "3e", "name61" => "mah", "sku64" => "3e", "name64" => "moh"]
The other holds simply id's: $array2 = [64, 74, 61]
edit for clarity: $array1 is a snippet of input from a post request i.e. $array1 = $request->all(); The numbers present within the keys of this array are unique Id's appended on form generation to distinguish between rows with multiple form elements.
Each row has an "update" checkbox also with an appended unique id. When ticked this id shows up in the request e.g. update64.
$array2 was populated by doing a foreach through the request, identifying the update string and isolating the id:
foreach ($array1 as $id => $value) {
$idInt = filter_var($id, FILTER_SANITIZE_NUMBER_INT);
$str = preg_replace('/[0-9]+/', '', $id);
if ($str === "update") {
array_push($array2, $idInt);
}
}
I want a solution that returns the elements from $array1 that have the appended ids found in $array2.
My own attempt looks like this:
$relevant_keys = function($key1, $key2) {
return ((preg_replace('/[0-9]+/', '', $key1) === $key2)) ? 1 : -1;
};
$filtered = array_intersect_ukey($array1, array_flip($array2), $relevant_keys);
However $filtered is returning empty and if I dd($key2) within the function it's not even returning an element from $array2, I get something from $array1 instead so this has left me confused.
Would appreciate any help.
Here's the solution to the exact problem you posted:
$filtered = [];
foreach ($array1 as $key => $value)
{
if ( ! preg_match('/(\d+)$/', $key, $matches)) continue;
if ( ! isset($matches[1]) || ! in_array($matches[1], $array2)) continue;
$filtered[$key] = $value;
}
But I'm not sure you're approaching this correctly. That input looks suspicious.
Are you sure there's no better way to format the request?
I have a few important insights to share based on your coding attempt.
array_intersect_ukey() should be the perfect function call for his task, but alas, it is not. I'll tell you why.
array_intersect_ukey() suffers in the same way as array_intersect_uassoc() and array_uintersect_uassoc() because the internal algorithm will stop looking for additional qualifying keys after it encounters its first one. I first came upon this reality here.
Also, the way that you've declared and used the custom function arguments ($key1 and $key2) indicates that you believe $key1 always relates to the first nominated array and $key2 always relates to the second nominated array. This is not true and I have seen many developers with this same false impression. The truth is that under the hood, the two parameters fed into the custom function may come from either array.
For the reasons in #1, I'll recommend that you shift your focus to array_filter(). By establishing a lookup array containing whitelisted keys and filtering on keys, you can swiftly filter your data. Inside the callback, I am using trim() to remove the letters before the id number at the end. This is just one way of isolating the whole number at the end of each key.
Code: (Demo)
$lookup = array_flip($array2);
var_export(
array_filter(
$array1,
fn($key) => isset($lookup[ltrim($key, 'a..z')]),
ARRAY_FILTER_USE_KEY
)
);
Output:
array (
'sku61' => '3e',
'name61' => 'mah',
'sku64' => '3e',
'name64' => 'moh',
)

Array Mapping function, returns false every time

Ok, trying to make a function that I can pass a variable to, that will search a static currently hardcoded multi dimensional array for its keys, and return the array matched to the key found (if found).
This is what I have thus far.
public function teamTypeMapping($teamType)
{
//we send the keyword football, baseball, other, then we return the array associated with it.
//eg: we send football to this function, it returns an array with nfl, college-football
$mappings = array(
"football" => array('nfl', 'college-football'),
"baseball" => array('mlb', 'college-baseball'),
"basketball" => array('nba', 'college-basketball'),
"hockey" => array('nhl', 'college-hockey'),
);
foreach($mappings as $mapped => $item)
{
if(in_array($teamType, $item)){return $mapped;}
}
return false;
}
And I'd like to make a call to it, example:
teamTypeMapping("football");
Amd have it return the array associated with the key "football", I have tried this a couple ways, and each time I come up false, maybe I am missing something so Im up for taking some advice at this point.
The reason it's not working is that you are looping through the $mappings array, and trying to see if $teamType is in the $item.
There are two problems with your approach:
You are looking in the $item (this is the array('nfl', 'college-football')) for 'football'. This is incorrect.
You are using in_array() which checks if a 'value' is in the array, not the 'key' that you have used. You might want to take a look at the array_key_exists() function - I think this is what you meant to use.
My personal preference is to use isset() instead of array_key_exists(). Slightly different syntax, but both do the same job.
See below for a revised solution:
public function teamTypeMapping($teamType)
{
//we send the keyword football, baseball, other, then we return the array associated with it.
//eg: we send football to this function, it returns an array with nfl, college-football
$mappings = array(
"football" => array('nfl', 'college-football'),
"baseball" => array('mlb', 'college-baseball'),
"basketball" => array('nba', 'college-basketball'),
"hockey" => array('nhl', 'college-hockey'),
);
if (isset($mappings[$teamType]))
{
return $mappings[$teamType];
}
return false;
}
I checked your function
public function teamTypeMapping($teamType)
{
//we send the keyword football, baseball, other, then we return the array associated with it.
//eg: we send football to this function, it returns an array with nfl, college-football
$mappings = array(
"football" => array('nfl', 'college-football'),
"baseball" => array('mlb', 'college-baseball'),
"basketball" => array('nba', 'college-basketball'),
"hockey" => array('nhl', 'college-hockey'),
);
foreach($mappings as $mapped => $item)
{
if(in_array($teamType, $item)){return $mapped;}
}
return false;
}
And when you like to make a call to it, example:
teamTypeMapping("football");
then it return false.
Solution is If your want the array then you want
foreach($mappings as $mapped => $item)
{
if($mapped == $teamType){return $mapped;}
}

How to return a key=>value pair from a function in PHP

I need to return a key value pair from a function. It would be preferable to retain the structure of the data. I would like to avoid creating an array with only one value if possible as I do not care for the syntax key($result[0]) or an array with two values, as I would like something with a syntax or structure that suggests the key=>value relationship between the values. Is there a more elegant alternative to the array for returning multiple values from a function in php?
You can only use array(), really.
return array("key1" => "value1", "key2" => "value2");
Anything else would just be uglier or more confusing.
How about:
function getData () {
return array('key','value');
}
list($key,$value) = getData();
echo $key." = ".$value;
Although I must say, this sounds like a bizarrely specific and largely cosmetic requirement...
Could you not return the values in an array, like so?
return array('key' => $key, 'value' => $value);
You could also do this:
return array($key => $value);
But that's involves more work to use after the fact, in my opinion.
Return an array.
return array("key" => "value");
Here a full example proposed by #polynomial that might be interesting:
//Function declaration with a return of a key value pair array
function getUserRating(){
return array(
'rating' => $rating,
'average' => $average
);
}
// Retrieve one of the key value pair
getUserRating()['rating'];
// Retrieve the other key value pair
getUserRating()['average'];
Think this kind of magic only work with PHP 7 or further? OMG! It Works with PHP 5.4!
Am I misunderstanding your question, or do you not want return array('aKey' => 'aVal');?

check is Array empty or not (php)

I am using Cakephp and try to customize the paginator result with some checkboxes .I was pass parameters in URL like this
"http://localhost/myproject2/browses/index/page:2/b.sonic:1/b.hayate:7/b.nouvo:2/b.others:-1/b.all:-2"
and cakephp translate URL to be the array like this
Array
(
[page] => 2
[b.sonic] => 1
[b.hayate] => 7
[b.nouvo] => 2
[b.others] => -1
[b.all] => -2
)
other time when I pass params without checking any checkbox.
"http://localhost/myproject2/browses/index/page:2"
and cakephp translate URL to be the array like this
Array
(
[page] => 2
)
how to simple check if [b.????] is available or not? I can't use !empty() function because array[page] is getting on the way.
If you want to check if a specific item is present, you can use either :
isset()
or array_key_exists()
But if you want to check if there is at least one item which has a key that starts with b. you will not have much choice : you'll have to loop over the array, testing each key.
A possible solution could look like this :
$array = array(
'page' => 'plop',
'b.test' => 150,
'b.glop' => 'huhu',
);
$found_item_b = false;
foreach (array_keys($array) as $key) {
if (strpos($key, 'b.') === 0) {
$found_item_b = true;
break;
}
}
if ($found_item_b) {
echo "there is at least one b.";
}
Another (possibly more fun, but not necessarily more efficient ^^ ) way would be to get the array of items which have a key that starts with b. and use count() on that array :
$array_b = array_filter(array_keys($array), function ($key) {
if (strpos($key, 'b.') === 0) {
return true;
}
return false;
});
echo count($array_b);
If page is always going to be there, you could simply do a count.
if (count($params) == 1) {
echo "There's stuff other than page!";
}
You could be more specific and check page is there and the count is one.
I think this is what you are looking for, the isset function so you would use it like...
if(isset(Array[b.sonic]))
{
//Code here
}

Categories