tarquino Posted December 12, 2014 Share Posted December 12, 2014 Hi all, I am using foreach statement to gather records and program levenshtein to detect any misspellings and suggesting the correct words. The thing is i am unable to convert all those strings into a single array. After trying to correct this issue so many times, i wonder if it is really possible to convert strings into a single array? Any input is welcome Quote Link to comment Share on other sites More sharing options...
cyberRobot Posted December 12, 2014 Share Posted December 12, 2014 It might help to see the code you have so far. When posting the code, please surround it with tags. Quote Link to comment Share on other sites More sharing options...
hansford Posted December 12, 2014 Share Posted December 12, 2014 Difficult to determine what you're after unless you post some code. There are many ways to convert strings into arrays. The whole string or just words/parts of the string. Post some code and a clear explanation of what you're trying to accomplish and let's get the party started! $string = "This is a string, whatever"; $args = explode(' ', $string); print_r( $args ); // output: Array ( [0] => This [1] => is [2] => a [3] => string, [4] => whatever ) $string = "Sentence number one. Sentence number two. Sentence number 3."; $args = explode('.', $string); $sentence_array = array(); foreach($args as $sentence) { if($sentence.length < 3) { continue; } $sentence_array[] = trim($sentence) . '.'; } print_r($sentence_array); // output: Array ( [0] => Sentence number one. [1] => Sentence number two. [2] => Sentence number 3. ) Quote Link to comment Share on other sites More sharing options...
tarquino Posted December 13, 2014 Author Share Posted December 13, 2014 Here is the code, the first part of the code outputs as separate strings. what i am trying to achieve is to convert all those values to a single array to check against using levenshtein. Currently it only checks against and provides only one suggestion, the last value of the string. is there any solution to this? the code is below: <?php $search = ""; if(isset($_GET["s"])) { $search = trim(htmlspecialchars($_GET["s"])); } if($search != "") { echo "<h1>Search term is set to <abbr style='text-transform:capitalize;'>{$search}</abbr></h1>"; } ?> <form action="index.php"> <input type="text" name="s" value="<?php echo $searchterm; ?>"/> <input type="submit" value="GO" /> </form> <?php $cakes = array(); $cakes = array( "jade" => array( "Chocolate Cake" => array( "ingredients" => "Chocolate, eggs, flour"), "Cookie Dough Cake" => array( "ingredients" => "Cookies, Double cream, flour, eggs") ), "jessica" => array( "Lemon Cheesecake" => array( "ingredients" => "Lemon, eggs, flour"), "Belgian Chocolate Cake" => array( "ingredients" => "Dark belgian chocolate, eggs, flour") ), "stephanie" => NULL, ); foreach($cakes as $cakeid => $cake) if(!empty($cake)) foreach($cake as $cakenames => $cakedescriptions) { $pieces = explode(",", $cakenames); foreach($pieces as $cakename) { var_dump($cakename); } } $input = $search; $words = array($cakename); //array('apple','pineapple','banana','orange', // 'radish','carrot','pea','bean','potato'); // no shortest distance found, yet $shortest = -1; // loop through words to find the closest foreach ($words as $word) { // calculate the distance between the input word, // and the current word $lev = levenshtein($input, $word); // check for an exact match if ($lev == 0) { // closest word is this one (exact match) $closest = $word; $shortest = 0; // break out of the loop; we've found an exact match break; } // if this distance is less than the next found shortest // distance, OR if a next shortest word has not yet been found if ($lev <= $shortest || $shortest < 0) { // set the closest match, and shortest distance $closest = $word; $shortest = $lev; } } echo "Input word: $input\n"; if ($shortest == 0) { echo "Exact match found: $closest\n"; } else { echo "Did you mean: $closest?\n"; } ?> Quote Link to comment Share on other sites More sharing options...
Solution QuickOldCar Posted December 13, 2014 Solution Share Posted December 13, 2014 This isn't the greatest thing to do as arrays can get huge, more work just to check for a typo. Lucene has this built in using fuzzy searches <?php if (isset($_GET['s']) && trim($_GET['s']) != '') { $search = strtolower(trim($_GET['s'])); } else { $search = ''; } ?> <form action="" method="get"> <input type="text" name="s" value="<?php echo $search;?>"/> <input type="submit" value="GO" /> </form> <?php $cakes = array( "jade" => array( "Chocolate Cake" => array( "ingredients" => "Chocolate, eggs, flour" ), "Cookie Dough Cake" => array( "ingredients" => "Cookies, Double cream, flour, eggs" ) ), "jessica" => array( "Lemon Cheesecake" => array( "ingredients" => "Lemon, eggs, flour" ), "Belgian Chocolate Cake" => array( "ingredients" => "Dark belgian chocolate, eggs, flour" ) ), "stephanie" => NULL ); $string = ''; //keep blank //find each word from the array values foreach ($cakes as $val) { if (is_array($val)) { foreach ($val as $key => $val2) { $string .= $key . " "; if (is_array($val)) { foreach ($val2 as $key => $val3) { if ($val3 != NULL || trim($val3) != '') { $string .= str_replace(",", " ", $val3) . " "; } } } } } } //remove whitespace and multiple spaces $string = preg_replace('/\s+/', ' ', strtolower(trim($string))); //explode the spaces in string and create an array $suggestions = array(); $suggestions = explode(" ", $string); $levenshtein = array(); //loop the suggestions array against levenshtein foreach ($suggestions as $suggestion) { $levenshtein[$suggestion] = levenshtein($search, $suggestion); } if (!empty($levenshtein)) { //sorted by lowest number of changes asort($levenshtein, SORT_NUMERIC); //show all weighted results echo "<pre>"; print_r($levenshtein); echo "</pre>"; //show only the closest results foreach ($levenshtein as $suggestion => $weight) { //weights of 1 or 2 usually the closest matches, zero is an exact match if ($weight > 0 && $weight < 3) { echo $suggestion . "<br />"; } } } ?> searching for coookie returns Array( [cookie] => 1 [cookies] => 2 [cake] => 4 [chocolate] => 5 [double] => 5 [lemon] => 6 [dark] => 6 [dough] => 6 [cream] => 6 [flour] => 6 [belgian] => 7 [eggs] => 7 [cheesecake] => 8) cookiecookies Quote Link to comment Share on other sites More sharing options...
tarquino Posted December 15, 2014 Author Share Posted December 15, 2014 thanks quickoldcar. the comments in the code were specially helpful. Quote Link to comment Share on other sites More sharing options...
tarquino Posted December 15, 2014 Author Share Posted December 15, 2014 once more question: should i wish to search the cake name array (without the ingredients) is it possible to do so, by deleting the following: if (is_array($val)) line Quote Link to comment Share on other sites More sharing options...
QuickOldCar Posted December 15, 2014 Share Posted December 15, 2014 You could remove this section and not do ingredients. if (is_array($val)) { foreach ($val2 as $key => $val3) { if ($val3 != NULL || trim($val3) != '') { $string .= str_replace(",", " ", $val3) . " "; } } } Quote Link to comment Share on other sites More sharing options...
tarquino Posted December 16, 2014 Author Share Posted December 16, 2014 You could remove this section and not do ingredients. if (is_array($val)) { foreach ($val2 as $key => $val3) { if ($val3 != NULL || trim($val3) != '') { $string .= str_replace(",", " ", $val3) . " "; } } } as opposed to separating each word and matching it to a search term, is it possible to suggest the individual cake names (ie. chocolate cake, lemon chesecake...) ? the reason i ask is because i tried toying with the explode string and it returns a blank value (nothing seems to be returned). Quote Link to comment Share on other sites More sharing options...
QuickOldCar Posted December 16, 2014 Share Posted December 16, 2014 (edited) I did it for complete words and trying to find close matches within the multiple words. Hopefully this helps you closer to what you need. <?php if (isset($_GET['s']) && trim($_GET['s']) != '') { $search = strtolower(trim($_GET['s'])); } else { $search = ''; } ?> <form action="" method="get"> <input type="text" name="s" value="<?php echo $search; ?>"/> <input type="submit" value="GO" /> </form> <?php $cakes = array( "jade" => array( "Chocolate Cake" => array( "ingredients" => "Chocolate, eggs, flour" ), "Cookie Dough Cake" => array( "ingredients" => "Cookies, Double cream, flour, eggs" ) ), "jessica" => array( "Lemon Cheesecake" => array( "ingredients" => "Lemon, eggs, flour" ), "Belgian Chocolate Cake" => array( "ingredients" => "Dark belgian chocolate, eggs, flour" ) ), "stephanie" => NULL ); $string = ''; //keep blank $levenshtein = array(); $exploded = array(); //find each word from the array values foreach ($cakes as $val) { if (is_array($val)) { foreach ($val as $key => $val2) { if (is_array($val)) { //explode multiple words $exploded = explode(" ", strtolower(trim($key))); if (!empty($exploded)) { //loop each exploded word foreach ($exploded as $explode) { //get each words weight $lev_weight = levenshtein($search, $explode); //if any of the words within range, add complete words to array if ($lev_weight >= 0 && $lev_weight <= 3) { $levenshtein[$key] = $lev_weight; } } } } } } } //only show if not an empty array if (!empty($levenshtein)) { asort($levenshtein, SORT_NUMERIC); //show raw results echo "<pre>"; print_r($levenshtein); echo "</pre>"; //loop items from array foreach ($levenshtein as $word => $weight) { echo $word . "<br />"; echo $weight . "<br />"; } } ?> results for chocolate Array( [belgian Chocolate Cake] => 0 [Chocolate Cake] => 0) Belgian Chocolate Cake0Chocolate Cake0 Edited December 16, 2014 by QuickOldCar Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.