litebearer Posted July 18, 2006 Share Posted July 18, 2006 Evening, all...I can't seem to get my thoughts properly wrapped around this problem.Scenario:Searching an array of data for matches to keywords. Create a new array from the matches.01. From 1 to 3 keywords possible. Match must have ALL keywords.02. Case insensitive03. $needle1, $needle2 and $needle3 represent the possible keywords 04. $old_haystack represents an element from the original array05. $haystack represents lowercase version of $old_haystack06. must be compatible with PHP versions 3, 4 and 5I came up with this sledge-hammer approach, looping through all of elements of the original array and runing this function on each element.However, I am sure there is a more elegant, refined and effective approach, but what is it?[code]<?PHPfunction validate_words($needle1, $needle2, $needle3, $old_haystack) { $haystack = strtolower($old_haystack); $new_element = ""; $kwl[0] = strlen(trim($needle1); $kwl[1] = strlen(trim($needle2); $kwl[2] = strlen(trim($needle3); $add_element = 0; if(($kwl[0]>0) AND ($kwl[1]>0) AND ($kwl[2]>0) AND (substr_count($haystack, $needle1)>0) AND (substr_count($haystack, $needle2)>0) AND (substr_count($haystack, $needle3)>0)) { // add element to new array return 1; } if(($kwl[0]>0) AND ($kwl[1]>0) AND ($kwl[2]<1) AND (substr_count($haystack, $needle1)>0) AND (substr_count($haystack, $needle2)>0)){ // add element to new array return 1; } if(($kwl[0]>0) AND ($kwl[1]<1) AND ($kwl[2]>0) AND (substr_count($haystack, $needle1)>0) AND (substr_count($haystack, $needle3)>0)) { // add element to new array return 1; } if(($kwl[0]>0) AND ($kwl[1]<1) AND ($kwl[2]<1) AND (substr_count($haystack, $needle1)>0)) { // add element to new array return 1; } if(($kwl[0]<1) AND ($kwl[1]>0) AND ($kwl[2]>0) AND (substr_count($haystack, $needle2)>0) AND (substr_count($haystack, $needle3)>0)) { // add element to new array return 1; } if(($kwl[0]><1) AND ($kwl[1]>0) AND ($kwl[2]<1) AND (substr_count($haystack, $needle2)>0)) { // add element to new array return 1; } if(($kwl[0]<1) AND ($kwl[1]<1) AND ($kwl[2]>0) AND (substr_count($haystack, $needle3)>0)) { // add element to new array return 1; } return 0;}?>[/code]Thanks,Lite... Link to comment https://forums.phpfreaks.com/topic/14908-searching-an-array-for-multiple-keywords/ Share on other sites More sharing options...
emehrkay Posted July 18, 2006 Share Posted July 18, 2006 im having trouble understanding exactly what you're trying to do.you use substr_count, but i thought $haystack was an array. it might just be easier to place your needles in one array and your haystack in another and loop though both - again, i dont understand what you are doing. can you explain a little bit more? Link to comment https://forums.phpfreaks.com/topic/14908-searching-an-array-for-multiple-keywords/#findComment-59779 Share on other sites More sharing options...
litebearer Posted July 18, 2006 Author Share Posted July 18, 2006 Hmmm, ok, a little more definition...First, I know that using mysql would simplify things; however, for various reasons, I am using a flatfile for this particular project.each line in the file represents a 'record'each record has several 'fields'user desires to search the file for all records that contain certain keywordsuser can use either 1, 2 or 3 keywords.user can select that either ALL or ANY of the keywords are in a recordMatching using ANY is no brainerThe code I previously posted will, in the end, accomplish the task.My basic question was/is: Is there a more effective, simpler method of reaching the same end resultNot sure if that makes it any clearer.Thanks,Lite... Link to comment https://forums.phpfreaks.com/topic/14908-searching-an-array-for-multiple-keywords/#findComment-59786 Share on other sites More sharing options...
akitchin Posted July 18, 2006 Share Posted July 18, 2006 try something like this:[code]<?php// define the needles$needle1 = 'one';$needle2 = 'two';$needle3 = 'three';// map a function to all levels of an arrayfunction deep_map($function, $val){ if (is_array($val)) { $return_arr = array(); foreach ($val AS $k => $v) $return_arr["$k"] = deep_map($function, $val["$k"]); return $return_arr; } else { $command = "return (".$function."(\$val));"; return eval($command); }}// the function to see if all the set needles match the elementfunction check_for_needles($haystack){ // check for needle1, but only if it's set if (isset($GLOBALS['needle1'])) { $results[] = (stristr($haystack, $GLOBALS['needle1']) !== FALSE) ? TRUE : FALSE; } // check for needle2, but only if it's set if (isset($GLOBALS['needle2'])) { $results[] = (stristr($haystack, $GLOBALS['needle2']) !== FALSE) ? TRUE : FALSE; } // check for needle3, but only if it's set if (isset($GLOBALS['needle3'])) { $results[] = (stristr($haystack, $GLOBALS['needle3']) !== FALSE) ? TRUE : FALSE; } // check if all set needles matched - return FALSE if they didn't, the element if they did if (in_array(FALSE, $results)) return FALSE; else return $element;}// run the function on your array haystack (can be multi-leveled)$matches = deep_map('check_for_needles', $haystack_array);// strip out the un-matching ones$matches = array_diff($matches, array(FALSE));// $matches will now contain all the matching elements, keys intact, at all levels?>[/code]may not be anymore elegant, but it might be easier to debug. the deep_map() is a function i made based on php.net entries, and will map the results of any defined function run on every element to an array with the same structure as the original (key => returned value for that element). keep this one handy, it helps in a LOT of applications.hth.[b]EDIT: just noticed you said they should be able to select whether ANY or ALL are matched. this can be adjusted by changing the if() condition in check_for_needles() to suit: checking whether there are any FALSEs vs. three FALSEs.[/b] Link to comment https://forums.phpfreaks.com/topic/14908-searching-an-array-for-multiple-keywords/#findComment-59787 Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.