How to sort an array by similarity in relation to an inputted word.

北战南征 提交于 2019-11-27 20:12:24

This could be a quick solution by using http://php.net/manual/en/function.similar-text.php:

This calculates the similarity between two strings as described in Programming Classics: Implementing the World's Best Algorithms by Oliver (ISBN 0-131-00413-1). Note that this implementation does not use a stack as in Oliver's pseudo code, but recursive calls which may or may not speed up the whole process. Note also that the complexity of this algorithm is O(N**3) where N is the length of the longest string.

$userInput = 'Bradley123';

$list = array('Bob', 'Brad', 'Britney');

usort($list, function ($a, $b) use ($userInput) {
    similar_text($userInput, $a, $percentA);
    similar_text($userInput, $b, $percentB);

    return $percentA === $percentB ? 0 : ($percentA > $percentB ? -1 : 1);
});

var_dump($list); //output: array("Brad", "Britney", "Bob");

Or by using http://php.net/manual/en/function.levenshtein.php:

The Levenshtein distance is defined as the minimal number of characters you have to replace, insert or delete to transform str1 into str2. The complexity of the algorithm is O(m*n), where n and m are the length of str1 and str2 (rather good when compared to similar_text(), which is O(max(n,m)**3), but still expensive).

$userInput = 'Bradley123';

$list = array('Bob', 'Brad', 'Britney');

usort($list, function ($a, $b) use ($userInput) {
    $levA = levenshtein($userInput, $a);
    $levB = levenshtein($userInput, $b);

    return $levA === $levB ? 0 : ($levA > $levB ? 1 : -1);
});

var_dump($list); //output: array("Britney", "Brad", "Bob");

You can use levenshtein function

<?php
// input misspelled word
$input = 'helllo';

// array of words to check against
$words  = array('hello' 'try', 'hel', 'hey hello');

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

?>

if you want to sort your array, you can do this:

$arr = array("hello", "try", "hel", "hey hello");
$search = "hey"; //your search var

for($i=0; $i<count($arr); $i++) {
   $temp_arr[$i] = levenshtein($search, $arr[$i]);
}
asort($temp_arr);
foreach($temp_arr as $k => $v) {
    $sorted_arr[] = $arr[$k];
}

$sorted_arr should then be in descending order starting with the closest word to your search term.

Another way is to use similar_text function which returns result in percents. See more http://www.php.net/manual/en/function.similar-text.php .

example for sorting multi array by similar_text https://3v4l.org/XUBDD#output

<?php
$json = '{
    "result": {
        "anime": [
            {
                "rowid": "2",
                "title": "Dusk Maiden of Amnesia",
                "pic": "\/\/i.imgur.com\/J4HRnHP.jpg",
                "slug": "Dusk-Maiden-of-Amnesia-dub",
                "year": "2012",
                "status": "done",
                "descript": "The story revolves around a first-year middle school student, Teiichi Niiya who had just enrolled at Seikyou Private Academy. When he gets lost in one of the schools old buildings, he meets a girl named Yuuko Kanoe who reveals herself as a ghost with no memories. Teiichi then decides to investigate her death by looking through the schools seven mysteries revolving around her. Throughout the story, Teiichi and Yuuko discover the truth about these ghost stories while helping those who are troubled.",
                "tags": "Mystery,,Romance,,School Club,,School Life,,Supernatural,,High School"
            },
            {
                "rowid": "12",
                "title": "Accel World",
                "pic": "https:\/\/i.imgur.com\/65gNsOX.png",
                "slug": "Accel-World-dub",
                "year": "2012",
                "status": "done",
                "descript": "Haruyuki+%22Haru%22+Arita+is+a+short%2C+overweight+boy+who+is+frequently+ridiculed+by+delinquents+at+the+Umesato+Junior+High+School.+Using+his+Neuro+Linker+to+escape+the+torment+of+real+life%2C+he+logs+onto+the+school%27s+Local+Network+cyberspace+where+he+always+plays+virtual+squash+alone%2C+and+his+innate+video+game+skills+bring+him+to+the+attention+of+Kuroyukihime+%28literally+meaning+%22Black+Snow+Princess%22%29%2C+the+school%27s+popular%2C+highly+intellectual+and+attractive+female+Student+Council+Vice-President.++After+helping+him+against+the+delinquents%2C+Kuroyukihime+introduces+Haruyuki+to+Brain+Burst%2C+a+secret+program+that+is+able+to+accelerate+the+human+cognitive+process+to+the+point+at+which+time+appears+to+stop.+Haruyuki+soon+learns+that+Brain+Burst+is+more+than+just+a+program%2C+but+an+Augmented+Reality+Massively+Multiplayer+Online+%28ARMMO%29+Fighting+Game+where+people+fight+each+other+in+fierce+duels+in+order+to+obtain+Burst+Points+which+can+be+spent+for+acceleration+abilities+in+the+real+world.",
                "tags": "Action,,Sci Fi,,Based On A Light Novel,,Futuristic,,Virtual Reality"
            },
            {
                "rowid": "7",
                "title": "Parasyte the maxim",
                "pic": "https:\/\/i.imgur.com\/AY7WkqY.jpg",
                "slug": "Parasyte-the-maxim-dub",
                "year": "2014",
                "status": "done",
                "descript": "17-year-old+Izumi+Shinichi+lives+with+his+mother+and+father+in+a+quiet+neighborhood+in+Tokyo.+One+night%2C+worm-like+aliens+called+Parasytes+invade+Earth%2C+taking+over+the+brains+of+human+hosts+by+entering+through+their+ears+or+noses.+One+Parasyte+attempts+to+crawl+into+Shinichi%27s+ear+while+he+sleeps%2C+but+fails+since+he+is+wearing+headphones%2C+and+enters+his+body+by+burrowing+into+his+arm+instead%2C+taking+over+his+right+hand+and+is+named+Migi.+Because+Shinichi+was+able+to+prevent+Migi+from+traveling+further+up+into+his+brain%2C+both+beings+retain+their+separate+intellect+and+personality.+As+the+duo+encounter+other+Parasytes%2C+they+capitalize+on+their+strange+situation+and+gradually+form+a+strong+bond%2C+working+together+to+survive.+This+gives+them+an+edge+in+battling+other+Parasytes%2C+who+frequently+attack+the+pair+upon+realization+that+Shinichi%27s+human+brain+is+still+intact.+Shinichi+feels+compelled+to+fight+other+Parasytes%2C+who+devour+humans+as+food%2C+while+enlisting+Migi%27s+help.",
                "tags": "Action,,Horror,,Sci Fi,,Aliens,,Body Sharing,,Bullying,,Explicit Violence,,Psychological"
            }
        ],
        "Current_page": "1",
        "Total_Pages": 75,
        "PerPage": 3,
        "Total": 224
    }
}';
$userInput = "maxim";
$jsonf = json_decode($json, true);
  usort($jsonf['result']['anime'], function ($a, $b) use ($userInput) {
    similar_text($userInput, $a['title'], $percentA);
    similar_text($userInput, $b['title'], $percentB);

    return $percentA === $percentB ? 0 : ($percentA > $percentB ? -1 : 1);
}); 
echo json_encode($jsonf);
?>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!