Search for PHP array element containing string [duplicate] - php

This question already has answers here:
Filter multidimensional array based on partial match of search value
(3 answers)
Closed 1 year ago.
$example = array('An example','Another example','Last example');
How can I do a loose search for the word "Last" in the above array?
echo array_search('Last example',$example);
The code above will only echo the value's key if the needle matches everything in the value exactly, which is what I don't want. I want something like this:
echo array_search('Last',$example);
And I want the value's key to echo if the value contains the word "Last".

To find values that match your search criteria, you can use array_filter function:
$example = array('An example','Another example','Last example');
$searchword = 'last';
$matches = array_filter($example, function($var) use ($searchword) { return preg_match("/\b$searchword\b/i", $var); });
Now $matches array will contain only elements from your original array that contain word last (case-insensitive).
If you need to find keys of the values that match the criteria, then you need to loop over the array:
$example = array('An example','Another example','One Example','Last example');
$searchword = 'last';
$matches = array();
foreach($example as $k=>$v) {
if(preg_match("/\b$searchword\b/i", $v)) {
$matches[$k] = $v;
}
}
Now array $matches contains key-value pairs from the original array where values contain (case- insensitive) word last.

function customSearch($keyword, $arrayToSearch){
foreach($arrayToSearch as $key => $arrayItem){
if( stristr( $arrayItem, $keyword ) ){
return $key;
}
}
}

$input= array('An example','Another example','Last example');
$needle = 'Last';
$ret = array_keys(array_filter($input, function($var) use ($needle){
return strpos($var, $needle) !== false;
}));
This will give you all the keys whose value contain the needle.

It finds an element's key with first match:
echo key(preg_grep('/\b$searchword\b/i', $example));
And if you need all keys use foreach:
foreach (preg_grep('/\b$searchword\b/i', $example) as $key => $value) {
echo $key;
}

The answer that Aleks G has given is not accurate enough.
$example = array('An example','Another example','One Example','Last example');
$searchword = 'last';
$matches = array();
foreach($example as $k=>$v) {
if(preg_match("/\b$searchword\b/i", $v)) {
$matches[$k] = $v;
}
}
The line
if(preg_match("/\b$searchword\b/i", $v)) {
should be replaced by these ones
$match_result = preg_match("/\b$searchword\b/i", $v);
if( $match_result!== false && $match_result === 1 ) {
Or more simply
if( preg_match("/\b$searchword\b/i", $v) === 1 ) {
In agreement with http://php.net/manual/en/function.preg-match.php
preg_match() returns 1 if the pattern matches given subject, 0 if it does not, or FALSE if an error occurred.

I do not like regex because as far as I know, they are always slower than a normal string function. So my solution is:
function substr_in_array($needle, array $haystack)
{
foreach($haystack as $value)
{
if(strpos($value, $needle) !== FALSE) return TRUE;
}
return FALSE;
}

I was also looking for a solution to OP's problem and I stumbled upon this question via Google. However, none of these answers did it for me so I came up with something a little different that works well.
$arr = array("YD-100 BLACK", "YD-100 GREEN", "YD-100 RED", "YJ-100 BLACK");
//split model number from color
$model = explode(" ",$arr[0])
//find all values that match the model number
$match_values = array_filter($arr, function($val,$key) use (&$model) { return stristr($val, $model[0]);}, ARRAY_FILTER_USE_BOTH);
//returns
//[0] => YD-100 BLACK
//[1] => YD-100 GREEN
//[2] => YD-100 RED
This will only work with PHP 5.6.0 and above.

Related

Search for matching partial values in an array [duplicate]

This question already has answers here:
Filter multidimensional array based on partial match of search value
(3 answers)
startsWith() and endsWith() functions in PHP
(34 answers)
Closed 1 year ago.
$target = 285
$array = array("260-315", "285-317", "240-320")
I need to search the array for the value that begins with the $target value. Also, the $target value will not be limited to 3 digits so I'm searching for a match of the digits before the hyphen.
So I want to end up with
$newTarget = 285-317
$finalTarget = 317
Note: I'm only searching for a match of the digits before the hyphen so "200-285" would not be a match
What you asked me in comment(below my answer),for that you can do it like below (My changed answer):-
<?php
$target = 285;
$array = array('260-315', '285-317', '240-320',"200-285");
foreach($array as $key=>$value){
if($target ==explode('-',$value)[0]){
echo $newTarget = $array[$key];
echo PHP_EOL;
echo $finalTarget = explode('-',$array[$key])[1];
}
}
?>
https://eval.in/702862
I can help you filter your array down to members that start with your target.
You can then split the return values to get to your final target.
<?php
$target = '285';
$array = array('260-315', '285-317', '240-320');
$out = array_filter($array, function($val) use ($target) {
return strpos($val, $target) === 0;
});
var_export($out);
Output:
array (
1 => '285-317',
)
<?php
$target = 285;
$arrStack = array(
"260-315",
"285-317",
"240-320",
);
$result = preg_grep('/'.$target.'/',$arrStack);
echo "<pre>"; print_r($result); echo "</pre>";
Something like this could work for you ? array_filter
$target = 285;
$array = array("260-315", "285-317", "240-320");
$newTarget = null;
$finalTarget = null;
$filteredArray = array_filter($array, function($val) use ($target) {
return strpos($val, $target."-") === 0;
});
if(isset($filteredArray[0])){
$newTarget = $filteredArray[0];
$finalTarget = explode($filteredArray[0], "-")[1];
}
Instead of finding what matches, you could exclude what doesn't match with array_filter.
For example:
$target = 285;
$original = array('260-315', '285-317', '240-320');
$final = array_filter($original, function ($value) use ($target) {
// Check if match starts at first character. Have to use absolute check
// because no match returns false
if (stripos($value, $target) === 0) {
return true;
}
return false;
});
The $final array will be a copy of the $original array without the non-matching values.
To output the first digits, you can then loop through your array of matches and get the value before the hyphen:
foreach ($final as $match) {
$parts = explode('-', $match);
if (is_array($parts) && ! empty($parts[0])) {
// Show or do something with value
echo $parts[0];
}
}
Use array_filter:
Example:
$target = '260';
$array = ['260-315', '285-317', '240-320'];
$matches = array_filter($array, function($var) use ($target) { return $target === explode('-', $var)[0]; });
print_r($matches);
Output:
Array
(
[0] => 260-315
)

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;
}
}

PHP: find biggest overlap between multiple strings

I have this array:
$array = array('abc123', 'ac123', 'tbc123', '1ac123');
I want to compare each string to each other and find the longest common substring. In the example above the result would be c123.
Update
I've completely misunderstood the question; the aim was to find the biggest overlap between an array of strings:
$array = array('abc123', 'ac123', 'tbc123', '1ac123');
function overlap($a, $b)
{
if (!strlen($b)) {
return '';
}
if (strpos($a, $b) !== false) {
return $b;
}
$left = overlap($a, substr($b, 1));
$right = overlap($a, substr($b, 0, -1));
return strlen($left) > strlen($right) ? $left : $right;
}
$biggest = null;
foreach ($array as $item) {
if ($biggest === null) {
$biggest = $item;
}
if (($biggest = overlap($biggest, $item)) === '') {
break;
}
}
echo "Biggest match = $biggest\n";
I'm not great at recursion, but I believe this should work ;-)
Old answer
I would probably use preg_grep() for that; it returns an array with the matches it found based on your search string:
$matches = preg_grep('/' . preg_quote($find, '/') . '/', $array);
Alternatively, you could use array_filter():
$matches = array_filter($array, function($item) use ($find) {
return strpos($item, $find) !== false;
});
I need to extract the value "c123" like it is the biggest match for all strings in array
I think what you would want to do here is then sort the above output based on string length (i.e. smallest string length first) and then take the first item:
if ($matches) {
usort($matches, function($a, $b) {
return strlen($a) - strlen($b);
});
echo current($matches); // take first one: ac123
}
Let me know if I'm wrong about that.
If you're just after knowing whether $find matches an element exactly:
$matching_keys = array_keys($array, $find, true); // could be empty array
Or:
$matching_key = array_search($find, $array, true); // could be false
Or event:
$have_value = in_array($find, $array, true);
in_array($find, $array);
returns true if it's in the array, but it has to be the exact match, in your case it won't finde 'ac123'.
if you want to see if it contains the string then you need to loop through the array and use a preg_match() or similar
You could use array_filter with a callback.
$output = array_filter ($input, function ($elem) { return false !== strpos ($elem, 'c123'); });
<?php
$array1 = array('abc123', 'ac123', 'tbc123', '1ac123');
if (in_array("c123", $array1)) {
echo "Got c123";
}
?>
You can use in_array as used here http://codepad.org/nOdaajNe
or use can use array_search as used here http://codepad.org/DAC1bVCi
see if it can help you ..
Documentation link : http://php.net/manual/en/function.array-search.php and http://www.php.net/manual/en/function.in-array.php

Find and replace duplicates in Array

I need to make app with will fill array with some random values, but if in array are duplicates my app not working correctly. So I need to write script code which will find duplicates and replace them with some other values.
Okay so for example i have an array:
<?PHP
$charset=array(123,78111,0000,123,900,134,00000,900);
function arrayDupFindAndReplace($array){
// if in array are duplicated values then -> Replace duplicates with some other numbers which ones I'm able to specify.
return $ArrayWithReplacedValues;
}
?>
So result shall be the same array with replaced duplicated values.
You can just keep track of the words that you've seen so far and replace as you go.
// words we've seen so far
$words_so_far = array();
// for each word, check if we've encountered it so far
// - if not, add it to our list
// - if yes, replace it
foreach($charset as $k => $word){
if(in_array($word, $words_so_far)){
$charset[$k] = $your_replacement_here;
}
else {
$words_so_far[] = $word;
}
}
For a somewhat-optimized solution (for cases where there are not that many duplicates), use array_count_values() (reference here) to count the number of times it shows up.
// counts the number of words
$word_count = array_count_values($charset);
// words we've seen so far
$words_so_far = array();
// for each word, check if we've encountered it so far
// - if not, add it to our list
// - if yes, replace it
foreach($charset as $k => $word){
if($word_count[$word] > 1 && in_array($word, $words_so_far)){
$charset[$k] = $your_replacement_here;
}
elseif($word_count[$word] > 1){
$words_so_far[] = $word;
}
}
Here the example how to generate unique values and replace recurring values in array
function get_unique_val($val, $arr) {
if ( in_array($val, $arr) ) {
$d = 2; // initial prefix
preg_match("~_([\d])$~", $val, $matches); // check if value has prefix
$d = $matches ? (int)$matches[1]+1 : $d; // increment prefix if exists
preg_match("~(.*)_[\d]$~", $val, $matches);
$newval = (in_array($val, $arr)) ? get_unique_val($matches ? $matches[1].'_'.$d : $val.'_'.$d, $arr) : $val;
return $newval;
} else {
return $val;
}
}
function unique_arr($arr) {
$_arr = array();
foreach ( $arr as $k => $v ) {
$arr[$k] = get_unique_val($v, $_arr);
$_arr[$k] = $arr[$k];
}
unset($_arr);
return $arr;
}
$ini_arr = array('dd', 'ss', 'ff', 'nn', 'dd', 'ff', 'vv', 'dd');
$res_arr = unique_arr($ini_arr); //array('dd', 'ss', 'ff', 'nn', 'dd_2', 'ff_2', 'vv', 'dd_3');
Full example you can see here webbystep.ru
Use the function
array_unique()
See more info at http://php.net/manual/en/function.array-unique.php
$uniques = array();
foreach ($charset as $value)
$uniques[$value] = true;
$charset = array_flip($uniques);

PHP Array values in string?

I have been looking around for a while in the PHP manual and can't find any command that does what I want.
I have an array with Keys and Values, example:
$Fields = array("Color"=>"Bl","Taste"=>"Good","Height"=>"Tall");
Then I have a string, for example:
$Headline = "My black coffee is cold";
Now I want to find out if any of the array ($Fields) values match somewhere in the string ($Headline).
Example:
Array_function_xxx($Headline,$Fields);
Would give the result true because "bl" is in the string $Headline (as a part of "Black").
I'm asking because I need performance... If this isn't possible, I will just make my own function instead...
EDIT - I'm looking for something like stristr(string $haystack , array $needle);
Thanks
SOLUTION - I came up with his function.
function array_in_str($fString, $fArray) {
$rMatch = array();
foreach($fArray as $Value) {
$Pos = stripos($fString,$Value);
if($Pos !== false)
// Add whatever information you need
$rMatch[] = array( "Start"=>$Pos,
"End"=>$Pos+strlen($Value)-1,
"Value"=>$Value
);
}
return $rMatch;
}
The returning array now have information on where each matched word begins and ends.
This should help:
function Array_function_xxx($headline, $fields) {
$field_values = array_values($fields);
foreach ($field_values as $field_value) {
if (strpos($headline, $field_value) !== false) {
return true; // field value found in a string
}
}
return false; // nothing found during the loop
}
Replace name of the function with what you need.
EDIT:
Ok, alternative solution (probably giving better performance, allowing for case-insensitive search, but requiring proper values within $fields parameter) is:
function Array_function_xxx($headline, $fields) {
$regexp = '/(' . implode('|',array_values($fields)) . ')/i';
return (bool) preg_match($regexp, $headline);
}
http://www.php.net/manual/en/function.array-search.php
that's what you looking for
example from php.net
<?php
$array = array(0 => 'blue', 1 => 'red', 2 => 'green', 3 => 'red');
$key = array_search('green', $array); // $key = 2;
$key = array_search('red', $array); // $key = 1;
?>

Categories