// lookup all hints from array if $q is different from ""
if ($q !== "") {
$q = strtolower($q);
$len=strlen($q);
foreach($a as $name) {
if (stristr($q, substr($name, 0, $len))) {
if ($hint === "") {
$hint = $name;
} else {
$hint .= ", $name";
}
}
}
}
The full thing is located at: http://www.w3schools.com/ajax/ajax_php.asp?
I don't really understand the part from the foreach and under but everything else including the ajax is understandable. Can someone explain mainly the
if (stristr($q, substr($name, 0, $len))) {
This is the only real roblem, I don't get. What exactly is this line doing :) Thanks
Thanks
IF block is executed if $q contains string $name length between 0 to length of $q.
For example if $q = "hello world" and $name = "hello" then IF is executed.
if $q = "hello world" and $name = "world" then If is not executed.
$len variable come's from your request length.
If you'r request is Hege len will be 4;
$name is one of them array value.
substr function getting array element with query lenght.
For example in our case our query length is 4. Second array element is Brittany from substr function we will get only brit stristr function will check Hege and Brti is equal or not.
here code start with
foreach($a as $name)
--> which will loop all names stored in $a array as $name.
--> and then substr($name, 0, $len).
where $len is the length of your query string parameter.
so, finally substr($name, 0, $len) return only that portion of string from stored name array starting from 0 to your query string length.
and after that stristr function.
which will find the first occurrence of your query string inside the returned portion of string from your stored name arrays with substr function and finally return the rest of the string.
so, at last $hint is initially blank variable. So at the end of the loop if only one match found then it only display single name and if more than one match found then it will display name with comma seprated.
Related
I have an array like below:
$fruits = array("apple","orange","papaya","grape")
I have a variable like below:
$content = "apple";
I need to filter some condition like: if this variable matches at least one of the array elements, do something. The variable, $content, is a bunch of random characters that is actually one of these available in the array data like below:
$content = "eaplp"; // it's a dynamically random char from the actual word "apple`
what have I done was like the below:
$countcontent = count($content);
for($a=0;$a==count($fruits);$a++){
$countarr = count($fruits[$a]);
if($content == $fruits[$a] && $countcontent == $countarr){
echo "we got".$fruits[$a];
}
}
I tried to count how many letters these phrases had and do like if...else... when the total word in string matches with the total word on one of array data, but is there something that we could do other than that?
We can check if an array contains some value with in_array. So you can check if your $fruits array contains the string "apple" with,
in_array("apple", $fruits)
which returns a boolean.
If the order of the letters is random, we can sort the string alphabetically with this function:
function sorted($s) {
$a = str_split($s);
sort($a);
return implode($a);
}
Then map this function to your array and check if it contains the sorted string.
$fruits = array("apple","orange","papaya","grape");
$content = "eaplp";
$inarr = in_array(sorted($content), array_map("sorted", $fruits));
var_dump($inarr);
//bool(true)
Another option is array_search. The benefit from using array_search is that it returns the position of the item (if it's found in the array, else false).
$pos = array_search(sorted($content), array_map("sorted", $fruits));
echo ($pos !== false) ? "$fruits[$pos] found." : "not found.";
//apple found.
This will also work but in a slightly different manner.
I split the strings to arrays and sort them to match eachoter.
Then I use array_slice to only match the number of characters in $content, if they match it's a match.
This means this will match in a "loose" way to with "apple juice" or "apple curd".
Not sure this is wanted but figured it could be useful for someone.
$fruits = array("apple","orange","papaya","grape","apple juice", "applecurd");
$content = "eaplp";
$content = str_split($content);
$count = count($content);
Foreach($fruits as $fruit){
$arr_fruit = str_split($fruit);
// sort $content to match order of $arr_fruit
$SortCont = array_merge(array_intersect($arr_fruit, $content), array_diff($content, $arr_fruit));
// if the first n characters match call it a match
If(array_slice($SortCont, 0, $count) == array_slice($arr_fruit, 0, $count)){
Echo "match: " . $fruit ."\n";
}
}
output:
match: apple
match: apple juice
match: applecurd
https://3v4l.org/hHvp3
It is also comparable in speed with t.m.adams answer. Sometimes faster sometimes slower, but note how this code can find multiple answers. https://3v4l.org/IbuuD
I think this is the simplest way to answer that question. some of the algorithm above seems to be "overkill".
$fruits = array("apple","orange","papaya","grape");
$content = "eaplp";
foreach ($fruits as $key => $fruit) {
$fruit_array = str_split($fruit); // split the string into array
$content_array = str_split($content); // split the content into array
// check if there's no difference between the 2 new array
if ( sizeof(array_diff($content_array, $fruit_array)) === 0 ) {
echo "we found the fruit at key: " . $key;
return;
}
}
What about using only native PHP functions.
$index = array_search(count_chars($content), array_map('count_chars', $fruits));
If $index is not null you will get the position of $content inside $fruits.
P.S. Be aware that count_chars might not be the fastest approach to that problem.
With a random token to search for a value in your array, you have a problem with false positives. That can give misleading results depending on the use case.
On search cases, for example wrong typed words, I would implement a filter solution which produces a matching array. One could sort the results by calculating the levenshtein distance to fetch the most likely result, if necessary.
String length solution
Very easy to implement.
False positives: Nearly every string with the same length like apple and grape would match.
Example:
$matching = array_filter($fruits, function ($fruit) use ($content) {
return strlen($content) == strlen($fruit);
});
if (count($matching)) {
// do your stuff...
}
Regular expression solution
It compares string length and in a limited way containing characters. It is moderate to implement and has a good performance on big data cases.
False positives: A content like abc would match bac but also bbb.
Example:
$matching = preg_grep(
'#['.preg_quote($content).']{'.strlen($content).'}#',
$fruits
);
if (count($matching)) {
// do your stuff...
}
Alphanumeric sorting solution
Most accurate but also a slow approach concerning performance using PHP.
False positives: A content like abc would match on bac or cab.
Example:
$normalizer = function ($value) {
$tokens = str_split($value);
sort($tokens);
return implode($tokens);
};
$matching = array_filter($fruits, function ($fruit) use ($content, $normalizer) {
return ($normalizer($fruit) == $normalizer($content));
});
if (count($matching)) {
// do your stuff...
}
Here's a clean approach. Returns unscrambled value early if found, otherwise returns null. Only returns an exact match.
function sortStringAlphabetically($stringToSort)
{
$splitString = str_split($stringToSort);
sort($splitString);
return implode($splitString);
}
function getValueFromRandomised(array $dataToSearch = [], $dataToFind)
{
$sortedDataToFind = sortStringAlphabetically($dataToFind);
foreach ($dataToSearch as $value) {
if (sortStringAlphabetically($value) === $sortedDataToFind) {
return $value;
}
}
return null;
}
$fruits = ['apple','orange','papaya','grape'];
$content = 'eaplp';
$dataExists = getValueFromRandomised($fruits, $content);
var_dump($dataExists);
// string(5) "apple"
Not found example:
$content = 'eaplpo';
var_dump($dataExists);
// NULL
Then you can use it (eg) like this:
echo !empty($dataExists) ? $dataExists . ' was found' : 'No match found';
NOTE: This is case sensitive, meaning it wont find "Apple" from "eaplp". That can be resolved by doing strtolower() on the loop's condition vars.
How about looping through the array, and using a flag to see if it matches?
$flag = false;
foreach($fruits as $fruit){
if($fruit == $content){
$flag = true;
}
}
if($flag == true){
//do something
}
I like t.m.adams answer but I also have a solution for this issue:
array_search_random(string $needle, array $haystack [, bool $strictcase = FALSE ]);
Description: Searches a string in array elements regardless of the position of the characters in the element.
needle: the caracters you are looking for as a string
haystack: the array you want to search
strictcase: if set to TRUE needle 'mood' will match 'mood' and 'doom' but not 'Mood' and 'Doom', if set to FALSE (=default) it will match all of these.
Function:
function array_search_random($needle, $haystack, $strictcase=false){
if($strictcase === false){
$needle = strtolower($needle);
}
$needle = str_split($needle);
sort($needle);
$needle = implode($needle);
foreach($haystack as $straw){
if($strictcase === false){
$straw = strtolower($straw);
}
$straw = str_split($straw);
sort($straw);
$straw = implode($straw);
if($straw == $needle){
return true;
}
}
return false;
}
if(in_array("apple", $fruits)){
true statement
}else{
else statement
}
I have a comma separated list of prefixes stored in a variable
$prefixes = “fa,go,urg”;
and a word stored in another variable
$word = “good”;
Now I want to know efficient way to check if any of the prefixes stored in $prefixes is the prefix of $word or not.
My intention is
If any of the prefixes stored in $prefixes is the prefix of the word stored in $word return TRUE.
If none of the prefixes stored in $prefixes is the prefix of the word stored in $word return FALSE.
Note:- Comma separated list of prefixes is provide by user using text box.
One thing that can be done is to have the prefixes within an array, and then check if $word is present within the array $preArr using in_array
in_array
(PHP 4, PHP 5, PHP 7)
in_array — Checks if a value exists in an array
$prefixes = “fa,go,urg”;
$preArr = explode(',', $prefixes); // Convert to array
$word = “good”;
if (in_array($word, $preArr)) {
echo "Success!";
} else {
echo "Failure!";
}
The substr function can achieve the desired result. It checks for the word good in the prefixes at specified location, which is the beginning of the word.
From the PHP Manual:
substr — Return part of a string
Description
string substr ( string $string , int $start [, int $length ] )
Returns the portion of string specified by the start and length parameters.
Try this:
$prefixes = “fa,go,urg”;
$word = “good”;
$Arr[] = explode(',', $prefixes); // Convert to array
$elements = count($Arr[]); //get total elements in array
for ($i=0;$i<count;$i++) {
if (substr( $Arr(i), 0, 4 ) === $word) {
return true;
}
else {return false;}
}
Your problem can be solved by a few ways, the most programmatic method being to just do a simple check, iterate across $prefixes and check it against 0.....i where i = N - 1 and N = count($prefixes[$i])
function inPrefixArr($prefixes, $word) {
$prefixesInArray = explode(',', $prefixes);
for ($i = 0; $i < count($prefixesInArray); i++) {
if (count($prefixesInArray[$i]) <= count($word)) {
if ($prefixesInArray[$i] == substr($word, 0, count($prefixesInArray[$i]))) {
return True;
}
}
}
return False
}
This checks if the any of the prefixes are a prefix of the word given in O(mn) time where m is the max length of some prefix in the array given. It is also the fastest and most space optimal solution that can be found.
As it seems you weren't asking for a theoretical/CS question, there are other interesting ways to implement this in other data structures which can yield better runtimes if you do this repeatedly.
When someone writes an entry in the textbox, I want to check the words that they used and find a match in a common word DB that I have. Each word in the DB had a number value that I need it to return.
I need to write an if statement that checks if a query returns a value, and if it does I need it to return -1.
This is what I have so far but right now but it only returns one word.
Entry::create($request->all());
// GETTING THE ARRY OF WORDS FROM entry_body( $entry_text)
$entry_text = $request->only('entry_body');
// REMOVE THE KEY AND JUST GET THE STRING VALUE
$entry_text = array_pull($entry_text,"entry_body");
$entry_noTag = strip_tags($entry_text);
// CONVERTE THE STRING ARRAY
$entry_explode = explode(" ", $entry_noTag);
// EACH WORD GETS ANALAYZED
$matched_words = Words::whereIn('word', $entry_explode)->get();
foreach ($entry_explode as $word) {
if ($matched_words == false){
return '-1';
}
else {
return $word;
}
};
I can get the code to return the matched values. What I need it to do is when a word in the array is not matched, it should return -1 so I know the word was not found in the DB.
Your first return will, of course, return and end the function. Put all values in array like this:
$arrayOfWords = array();
foreach ($matched_words as $word) {
if (in_array($word->word,$entry_explode)) {
$arrayOfWords['found'][] = $word->word;
} else {
$arrayOfWords['notFound'][] = $word->word;
}
}
return $arrayOfWords;
I've spent half day trying to figure out this and finally I got working solution.
However, I feel like this can be done in simpler way.
I think this code is not really readable.
Problem: Find first non-repetitive character from a string.
$string = "abbcabz"
In this case, the function should output "c".
The reason I use concatenation instead of $input[index_to_remove] = ''
in order to remove character from a given string
is because if I do that, it actually just leave empty cell so that my
return value $input[0] does not not return the character I want to return.
For instance,
$str = "abc";
$str[0] = '';
echo $str;
This will output "bc"
But actually if I test,
var_dump($str);
it will give me:
string(3) "bc"
Here is my intention:
Given: input
while first char exists in substring of input {
get index_to_remove
input = chars left of index_to_remove . chars right of index_to_remove
if dupe of first char is not found from substring
remove first char from input
}
return first char of input
Code:
function find_first_non_repetitive2($input) {
while(strpos(substr($input, 1), $input[0]) !== false) {
$index_to_remove = strpos(substr($input,1), $input[0]) + 1;
$input = substr($input, 0, $index_to_remove) . substr($input, $index_to_remove + 1);
if(strpos(substr($input, 1), $input[0]) == false) {
$input = substr($input, 1);
}
}
return $input[0];
}
<?php
// In an array mapped character to frequency,
// find the first character with frequency 1.
echo array_search(1, array_count_values(str_split('abbcabz')));
Python:
def first_non_repeating(s):
for i, c in enumerate(s):
if s.find(c, i+1) < 0:
return c
return None
Same in PHP:
function find_first_non_repetitive($s)
{
for($i = 0; i < strlen($s); $i++) {
if (strpos($s, $s[i], $i+1) === FALSE)
return $s[i];
}
}
Pseudocode:
Array N;
For each letter in string
if letter not exists in array N
Add letter to array and set its count to 1
else
go to its position in array and increment its count
End for
for each position in array N
if value at potition == 1
return the letter at position and exit for loop
else
//do nothing (for clarity)
end for
Basically, you find all distinct letters in the string, and for each letter, you associate it with a count of how many of that letter exist in the string. then you return the first one that has a count of 1
The complexity of this method is O(n^2) in the worst case if using arrays. You can use an associative array to increase it's performance.
1- use a sorting algotithm like mergesort (or quicksort has better performance with small inputs)
2- then control repetetive characters
non repetetive characters will be single
repetetvives will fallow each other
Performance : sort + compare
Performance : O(n log n) + O(n) = O(n log n)
For example
$string = "abbcabz"
$string = mergesort ($string)
// $string = "aabbbcz"
Then take first char form string then compare with next one if match repetetive
move to the next different character and compare
first non-matching character is non-repetetive
This can be done in much more readable code using some standard PHP functions:
// Count number of occurrences for every character
$counts = count_chars($string);
// Keep only unique ones (yes, we use this ugly pre-PHP-5.3 syntax here, but I can live with that)
$counts = array_filter($counts, create_function('$n', 'return $n == 1;'));
// Convert to a list, then to a string containing every unique character
$chars = array_map('chr', array_keys($counts));
$chars = implode($chars);
// Get a string starting from the any of the characters found
// This "strpbrk" is probably the most cryptic part of this code
$substring = strlen($chars) ? strpbrk($string, $chars) : '';
// Get the first character from the new string
$char = strlen($substring) ? $substring[0] : '';
// PROFIT!
echo $char;
$str="abbcade";
$checked= array(); // we will store all checked characters in this array, so we do not have to check them again
for($i=0; $i<strlen($str); $i++)
{
$c=0;
if(in_array($str[$i],$checked)) continue;
$checked[]=$str[$i];
for($j=$i+1;$j<=strlen($str);$j++)
{
if($str[$i]==$str[$j])
{
$c=1;
break;
}
}
if($c!=1)
{
echo "First non repetive char is:".$str[$i];
break;
}
}
This should replace your code...
$array = str_split($string);
$array = array_count_values($array);
$array = array_filter($array, create_function('$key,$val', 'return($val == 1);'));
$first_non_repeated_letter = key(array_shift($array));
Edit: spoke too soon. Took out 'array_unique', thought it actually dropped duplicate values. But character order should be preserved to be able to find the first character.
Here's a function in Scala that would do it:
def firstUnique(chars:List[Char]):Option[Char] = chars match {
case Nil => None
case head::tail => {
val filtered = tail filter (_!=head)
if (tail.length == filtered.length) Some(head) else firstUnique(filtered)
}
}
scala> firstUnique("abbcabz".toList)
res5: Option[Char] = Some(c)
And here's the equivalent in Haskell:
firstUnique :: [Char] -> Maybe Char
firstUnique [] = Nothing
firstUnique (head:tail) = let filtered = (filter (/= head) tail) in
if (tail == filtered) then (Just head) else (firstUnique filtered)
*Main> firstUnique "abbcabz"
Just 'c'
You can solve this more generally by abstracting over lists of things that can be compared for equality:
firstUnique :: Eq a => [a] -> Maybe a
Strings are just one such list.
Can be also done using array_key_exists during building an associative array from the string. Each character will be a key and will count the number as value.
$sample = "abbcabz";
$check = [];
for($i=0; $i<strlen($sample); $i++)
{
if(!array_key_exists($sample[$i], $check))
{
$check[$sample[$i]] = 1;
}
else
{
$check[$sample[$i]] += 1;
}
}
echo array_search(1, $check);
Just looked at function
str_pad($input, $pad_length, $pad_str, [STR_PAD_RIGHT, STR_PAD_LEFT, or STR_PAD_BOTH])
which helps to pad some string on left, right or on both sides of a given input.
Is there any php function which I can use to insert a string inside an input string?
for example ..
$input = "abcdef";
$pad_str = "#";
so if I give insert index 3, it inserts "#" after first 3 left most characters and $input becomes "abc#def".
thanks
You're looking for a string insert, not a padding.
Padding makes a string a set length, if it's not already at that length, so if you were to give a pad length 3 to "abcdef", well it's already at 3, so nothing should happen.
Try:
$newstring = substr_replace($orig_string, $insert_string, $position, 0);
PHP manual on substr_replace
you need:
substr($input, 0, 3).$pad_str.substr($input, 3)
Bah, I misread the question. You want a single insert, not insert every X characters. Sorry.
I'll leave it here so it's not wasted.
You can use regular expressions and some calculation to get your desired result (you probably could make it with pure regexp, but that would be more complex and less readable)
vinko#mithril:~$ more re.php
<?php
$test1 = "123123123";
$test2 = "12312";
echo puteveryXcharacters($a,"#",3);
echo "\n";
echo puteveryXcharacters($b,"#",3);
echo "\n";
echo puteveryXcharacters($b,"$",3);
echo "\n";
function puteveryXcharacters($str,$wha,$cnt) {
$strip = false;
if (strlen($str) % $cnt == 0) {
$strip = true;
}
$tmp = preg_replace('/(.{'.$cnt.'})/',"$1$wha", $str);
if ($strip) {
$tmp = substr($tmp,0,-1);
}
return $tmp;
}
?>
vinko#mithril:~$ php re.php
123#123#123
123#12
123$12