Sorting foreach results

I have the following code that is displaying the results of a simply foreach statement. What I want to do is order the results by $lev from lowest value to highest value. Any ideas?

// input misspelled word
 $input = 'carrrot';

// array of words to check against
$words  = array('apple','pineapple','banana','orange', 'radish','carrot','pea','bean','potato');

//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);
	
	
	if($lev <= 10) {
	echo $word."-".$lev."<br>";
	}

}

I think I would put together an array using the word as the key and the distance as the value.
Then sort using that array. and display the key names

Could you give an example of this?

If you don’t need to keep the levenshtein rating for anything else, you could just use the usort function, something like this:

$input = 'carrrot';

$words  = array('apple','pineapple','banana','orange', 'radish','carrot','pea','bean','potato');

usort($words, function($a, $b) use ($input) {
    $levA = levenshtein($input, $a);
    $levB = levenshtein($input, $b);

    if ($levA == $levB) {
        return 0;
    }

    return ($levA < $levB) ? -1 : 1;
});

// $words is now sorted by levenshtein score (lowest first)
1 Like

You’ve lost me at the ($a, $b) bit. Wouldn’t you should have to do this against one of the words?

The idea is that usort takes an array and passes pairs of elements to the function that you provide as the second argument. That function has to take the two values and compare them somehow, returning 0 if they are equivalent, -1 if the first element should come before the second, and 1 if it should come after. This happens until all the elements in the array have been sorted.

You can read more about it in the PHP manual.

It would be nice to keep the levenstein rating. The ouput of the usort is not really outputting the way the rest of the script will need it. Is there another way to go about this?

Sure, you could do something like this:

$scores = array();

foreach ($words as $word) {
    $score = levenshtein($input, $word);
    $scores[$word] = $score;
}

asort($scores);

which will give you a sorted array where the words are the keys, and the scores are the values. Running it on your example word list would give the following output:

array(9) {
  ["carrot"]=>
  int(1)
  ["potato"]=>
  int(6)
  ["apple"]=>
  int(6)
  ["radish"]=>
  int(6)
  ["orange"]=>
  int(6)
  ["banana"]=>
  int(6)
  ["bean"]=>
  int(7)
  ["pea"]=>
  int(7)
  ["pineapple"]=>
  int(9)
}

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.