I'm trying to use in_array or something like it for associative or more complex arrays.
This is the normal in_array
in_array('test', array('test', 'exists')); //true
in_array('test', array('not', 'exists')); // false
What I'm trying to search is a pair, like the combination 'test' and 'value'. I can set up the combo to be searched to array('test','value') or 'test'=>'value' as needed. But how can I do this search if the array to be searched is
array('test'=>'value', 'exists'=>'here');
or
array( array('test','value'), array('exists'=>'here') );
if (
array_key_exists('test', $array) && $array['test'] == 'value' // Has test => value
||
in_array(array('test', 'value'), $array) // Has [test, value]
) {
// Found
}
If you want to see if there is a key "test" with a value of "value" then try this:
<?php
$arr = array('key' => 'value', 'key2' => 'value');
if(array_key_exists('key',$arr) && $arr['key'] == 'value'))
echo "It is there!";
else
echo "It isn't there!";
?>
If I understand you correctly, you're looking for a function called array_search()
It accepts a mixed value, so you can even search for objects - I haven't tried it exactly, but it should work for your use case:
if (array_search(array('test','value'), array(array('test','value'),array('nottest','notvalue'))) !== false) {
// item found...
}
ok..
However I think you'll find this method the most useful:
If you just need to find out if a certain key/value pair is located in an array, the easiest way to do it is like this:
<?php
if (isset($arr['key']) && $arr['key'] == 'value') {
// we have a match...
}
?>
if you need to find something in a more complex pattern, there's no avoid creating a bigger loop.
Separate Keys from Values and use in_array()
$myArray = array('test'=>'value', 'exists'=>'here');
array_keys($myArray)
array_values($myArray)
Related
I would like to check all keys of a global GET array and do something, if it contains keys, other than some whitelisted ones from an array.
Let's say the current url is:
.../index.php?randomekey1=valueX&randomkey2=valueY&acceptedkey1=valueZ&randomkey3=valueA&acceptedkey2=valueB
Just for better visualization:
These GET parameters are all available in the global GET variable which looks something like this:
$GET = array(
"randomekey1" => "valueX",
"randomkey2" => "valueY",
"acceptedkey1" => "valueZ",
"randomkey3" => "valueA",
"acceptedkey2" => "valueB"
);
The keys I accept and want to let pass, I put into an array too:
$whitelist = array(
"acceptedkey1",
"acceptedkey2",
"acceptedkey3",
);
Now I want to check whether $GET contains any key other than the whitelisted. So in the URL example from above it should return "true", because there are keys in the $GET array which aren't in the whitelist.
Not only the existence of such an unknown (none whitelisted) key should trigger a true, but please also its emptyness!
Another example would be the following url:
.../index.php?acceptedkey1=valueZ&acceptedkey3=valueB
This should return false, because no other key other than the ones in the whitelist were found.
Unfortunately I was not able to find any modification of the in_array function or array_search which would fit these requirements, because as far as I know these functions are only looking for something specific, whereas in my requirements I am also looking for something specific (the whitelist keys), but at the same tme I have to check if some unknown keys exist.
Thank you.
It seems you want to determine whether an array contains keys that don't exist in a whitelist.
One way to find the difference between arrays is to use array_diff():
array_diff ( array $array1 , array $array2 [, array $... ] ) : array
Returns an array containing all the entries from array1 that are not present in any of the other arrays.
So, it can be used to return all keys from the URL that are not present in the whitelist:
$extrasExist = !empty( array_diff( array_keys($GET), $whitelist ) );
var_dump($extrasExist);
Here's a demonstration:
$get1 = array(
"randomekey1" => "valueX",
"randomkey2" => "valueY",
"acceptedkey1" => "valueZ",
"randomkey3" => "valueA",
"acceptedkey2" => "valueB"
);
$get2 = array(
"acceptedkey1" => "valueZ",
"acceptedkey2" => "valueB"
);
$whitelist = array(
"acceptedkey1",
"acceptedkey2",
"acceptedkey3"
);
$extrasExist = !empty(array_diff(array_keys($get1),$whitelist));
var_dump($extrasExist);
$extrasExist = !empty(array_diff(array_keys($get2),$whitelist));
var_dump($extrasExist);
bool(true)
bool(false)
Everything in PHP doesn't have to be all "lets find function that does exactly what I'm looking for". Just do a simple foreach loop, which can accomplish what you're looking for:
function clear_filter() {
$whitelist = array( "project", "table_name", "filterDates", );
foreach ($_GET as $gkey => $gval) {
if (!in_array($gkey, $whitelist)) {
return false;
}
}
return true;
}
You can also write it more simply, with one foreach loop like below:
function isValid() {
// Copy the array
$temp = $_GET;
// Loop through the array, and remove any whitelisted elements
foreach ($whitelist as $wkey) {
unset($temp[$wkey]);
}
// If count($temp) > 0, there are non whitelisted entries in the array.
return count($temp) === 0;
}
You can use the following function.
$check = checkWhitliest( $_GET, $whitelist ) );
var_dump ($check );
You can call the above function as
function checkWhitliest( $array, $whitelist ) {
$allKeys = array_keys ( $array); //Get all Keys from the array.
$diff = array_diff( $allKeys, $whitelist); //Get the values which are not in whitelist.
if( count ( $diff ) > 0 ) { //If the count is greater than 0, then there are certain extra kesy in $_GET
return true;
}
return false;
}
There are only two techniques that I would recommend for this task and both make key comparisons for performance reasons. Using array_diff() or in_array() will always be slower than array_diff_key() and isset(), respectively, because of how PHP treats arrays as hash maps.
If you don't mind iterating the entire $GET array (because its data is relatively small), then you can concisely flip the whitelist array and check for any key differences.
var_export(
(bool)array_diff_key($GET, array_flip($whitelist))
);
If performance is more important than code brevity, then you should craft a technique that uses a conditional break or return as soon as a non-whitelisted key is encountered -- this avoids doing pointless iterations after the outcome is decided.
$hasNotWhitelisted = false;
$lookup = array_flip($whitelist);
foreach ($GET as $key => $value) {
if (isset($lookup[$key])) {
$hasNotWhitelisted = true;
break;
}
}
var_export($hasNotWhitelisted);
Or
function hasNotWhitelisted($array, $whitelist): bool {
$lookup = array_flip($whitelist);
foreach ($array as $key => $value) {
if (isset($lookup[$key])) {
return true;
}
}
return false;
}
var_export(hasNotWhitelisted($GET, $whitelist));
All of the above techniques deliver a true result for the sample data. Demo of all three snippets.
$items1 = ['apple', 'tree', 'juice'];
$items2 = ['apple', 'tree'];
$items3 = ['apple'];
// loop
If ($items[i].containsOnly['apple'])
{
// do something..
}
In the simplified example above I want to get the array that matches the given item. Is there a method available similar to 'containsOnly'? Or what is the best way to do this?
//If the array has the only item present
if(in_array('apple',$item) && count($item)==1)
{
//Do Something
}
Couple your logic with count:
function containsOnly($a, $v)
{
return count($a) === 1 && array_values($a)[0] === $v;
}
This will ensure that you have only one item and the value is equal to what you are searching for.
Note: The usage of array_values here is to reset all the indexes so we can ensure [0] is where the value will be. Instead of the array_values variation you can use in_array if you prefer that.
You could create a collection of item groups, ->filter() by the condition, then run code on ->each item group which passed the condition.
$itemGroups[] = ['apple', 'tree', 'juice'];
$itemGroups[] = ['apple', 'tree'];
$itemGroups[] = ['apple'];
collect($itemGroups)
->filter(function($items, $key) {
return count($items) == 1 && in_array('apple', $items);
})
->each(function($items, $key) {
// do something
});
You can use the method contains. From the Laravel documentation:
$collection = collect(['name' => 'Desk', 'price' => 100]);
$collection->contains('Desk');
// true
$collection->contains('New York');
// false
I think the example is fairly simple. In your example it would look something like:
$collection = $items1->merge($items2)->merge($items3)
if($collection->contains('apple') && $collection->count() === 1){
// it contains apple
}
Not tested tho but you get the idea behind it.
try this:
$items=array_merge($items1,$items2,$items3);
if (in_array("apple", $items)){
echo "success";
}
I have an array like this:
Array(
[0]=>Array([uploaderName]=>x[uploadedImageName]=>k6gIjfO[uploaderIp]=>195.155.116.217[uploader]=>e0699587cbfd[uploadedServer]=>alpha)
[1]=>Array([uploaderName]=>x[uploadedImageName]=>byUTyJo[uploaderIp]=>195.155.116.217[uploader]=>e0699587cbfd[uploadedServer]=>alpha)
[2]=>Array([uploaderName]=>x[uploadedImageName]=>oSVEnNk[uploaderIp]=>195.155.116.217[uploader]=>e0699587cbfd[uploadedServer]=>alpha)
[3]=>Array([uploaderName]=>x[uploadedImageName]=>Dj7GRYS[uploaderIp]=>195.155.116.217[uploader]=>e0699587cbfd[uploadedServer]=>alpha)
[4]=>Array([uploaderName]=>x[uploadedImageName]=>upsb8IC[uploaderIp]=>195.155.116.217[uploader]=>e0699587cbfd[uploadedServer]=>alpha)
[5]=>Array([uploaderName]=>x[uploadedImageName]=>YoEEzGi[uploaderIp]=>195.155.116.217[uploader]=>e0699587cbfd[uploadedServer]=>alpha)
[6]=>Array([uploaderName]=>x[uploadedImageName]=>st3dLNs[uploaderIp]=>195.155.116.217[uploader]=>e0699587cbfd[uploadedServer]=>alpha)
[7]=>Array([uploaderName]=>x[uploadedImageName]=>LBNpiIG[uploaderIp]=>195.155.116.217[uploader]=>e0699587cbfd[uploadedServer]=>alpha)
[8]=>Array([uploaderName]=>x[uploadedImageName]=>mFYDmBG[uploaderIp]=>195.155.116.217[uploader]=>e0699587cbfd[uploadedServer]=>alpha)
[9]=>Array([uploaderName]=>x[uploadedImageName]=>z03kSx1[uploaderIp]=>195.155.116.217[uploader]=>e0699587cbfd[uploadedServer]=>alpha)
)
I want to get any image's data from this array.
Example: When user shows uploadedImageName == jCPjeWv, I wan't to get who is it's uploader.
Simple, just use foreach
$arr = array(/* content here */);
foreach($arr as $value){
if($value['uploadedImageName'] == 'jCPjeWv'){
echo $value['uploaderName'];
break;
}
}
Just for fun, here's another way:
echo array_column($array, 'uploaderName', 'uploadedImageName')['jCPjeWv'];
Get an array of uploaderName with the index set to uploadedImageName
Access the index using the uploadedImageName 'jCPjeWv'
Obviously to do it multiple times you would want to actually create a new array:
$images = array_column($array, 'uploaderName', 'uploadedImageName');
echo $images['jCPjeWv'];
If you want to access the other values as well, then use null instead of uploaderName:
$images = array_column($array, null, 'uploadedImageName');
echo $images['jCPjeWv']['uploaderName'];
echo $images['jCPjeWv']['uploaderIp'];
NOTE: These ways only work if the uploadedImageName is unique.
A foreach is possible, but I think it's important to learn the array functions as well so I'm just going to put this example here.
$uploadedImageName = 'jCPjeWv';
$filtered = array_filter($array, function($value) use ($uploadedImageName) {
return ($value['uploadedImageName'] == $uploadedImageName);
});
This will return a $filtered with the other arrays removed since their $value['uploadedImageName'] will not equal $uploadedImageName.
For more info check out the http://php.net/manual/en/function.array-filter.php manual.
This question already has answers here:
Most efficient way to search for object in an array by a specific property's value
(11 answers)
Closed 4 months ago.
I Have an array holding multiple objects. Is it posible to check if a value exists in any one of the objects e.g. id->27 without looping? In a similar fashion to PHP's in_array() function. Thanks.
> array(10)[0]=>Object #673
["id"]=>25
["name"]=>spiderman
[1]=>Object #674
["id"]=>26
["name"]=>superman
[2]=>Object #675
["id"]=>27
["name"]=>superman
.......
.......
.........
No. If you often need quick direct lookup of values, you need to use array keys for them, which are lightning fast to lookup. For example:
// prepare once
$indexed = array();
foreach ($array as $object) {
$indexed[$object->id] = $object;
}
// lookup often
if (isset($indexed[42])) {
// object with id 42 exists...
}
If you need to lookup objects by different keys, so you can't really index them by one specific key, you need to look into different search strategies like binary searches.
$results = array_filter($array, function($item){
return ($item->id === 27);
});
if ($results)
{
.. You have matches
}
You will need to do looping one way or another - but you don't have to manually implement the loop yourself. Have a look at array_filter function. All you need to do is to provide a function that checks the objects, something like this:
function checkID($var)
{
return $var->id == 27;
}
if(count(array_filter($input_array, "checkID"))) {
// you have at least one matching element
}
Or you can even do this in one line:
if(count(array_filter($input_array, function($var) { return $var->id == 27; }))) {
// you have at least one matching element
}
You may want to combine two functions to get the desired results.
array_search($needle, array_column($array, 'key_field');
Created a small code to demonstrate its use.
<?php
$superheroes = [
[
"id" => 1,
"name" => "spiderman"
],
[
"id" => 2,
"name" => "superman"
],
[
"id" => 3,
"name" => "batman"
],
[
"id" => 4,
"name" => "robin"
],
];
$needle = 'spiderman';
$index = array_search($needle, array_column($superheroes, "name"));
echo "Is $needle a superhero?<br/>";
//Comparing it like this is important because if the element is found at index 0,
//array_search will return 0 which means false. Hence compare it with !== operator
if ( false !== $index ) {
echo "yes";
} else {
echo "no";
}
?>
You can do:
foreach ($array as $value)
{
if ($value == "what you are looking for")
break;
}
array_search — Searches the array for a given value and returns the
corresponding key if successful
$key = array_search('your search', $array);
I want to remove an element from a PHP array (and shrink the array size). Just looking at the PHP docs, it seems this can be done using array_slice() and array_merge()
so I am guessing (off the top of my head) that some combination of array_merge() and array_slice will work. However, array_slice() requires an index (not a key), so I'm not sure how to quickly cobble these functions together for a solution.
Has anyone implemented such a function before?. I'm sure it must be only a few lines long, but I cant somehow get my head around it (its been one of those days) ...
Actually, I just came up with this cheesy hack when writing up this question....
function remove_from_array(array $in, value) {
return array_diff($in, (array)$value);
}
too ugly? or will it work (without any shocking side effects)?
This functionality already exists; take a look at unset.
http://php.net/manual/en/function.unset.php
$a = array('foo' => 'bar', 'bar' => 'gork');
unset($a['bar']);
print_r($a);
output will be:
array(
[foo] => bar
)
There's the array_filter function that uses a callback function to select only wanted values from the array.
you want an unset by value. loop through the array and unset the key by value.
unset($my_array['element']);
Won't work?
This code can be replaced by single array_filter($arr) call
foreach($array as $key => $value) {
if($value == "" || $value == " " || is_null($value)) {
unset($array[$key]);
}
}
/*
and if you want to create a new array with the keys reordered accordingly...
*/
$new_array = array_values($array);