字符串比较,无论PHP顺序如何

I want to know if there is a way to compare by means of some PHP method, and verify that two chains regardless of the order are the same,

for example:

     $string1 = "Pedro Perez";
     $string2 = "Perez Pedro";

So my question is how can I make this TRUE in a comparison. Clearly, your order makes it different.


I ask this question because I am developing a search, and I want a comparison of $string1 and $string2 to be taken as the same value, regardless of the order they have, as long as the string has the same words

You can try doing this.

  1. Convert the string into an array by splitting on spaces.
  2. Sort the array.
  3. Convert back the array into string.
  4. Compare both.

In simple ways, here you go...

<?php
  $string1 = "Pedro Perez";
  $string2 = "Perez Pedro";
  $string1 = explode(" ", $string1);
  $string2 = explode(" ", $string2);
  // Update: You don't save the output of sort, as it's by reference.
  sort($string1);
  sort($string2);
  $string1 = implode(" ", $string1);
  $string2 = implode(" ", $string2);
  var_dump($string1 === $string2);
?>

You explode it by space and intersect both arrays as follows and check its count

$string1 = "Pedro Perez";
$string2 = "Perez Pedro";
$s1 = array_unique(explode(" ", $string1));
$s2 = array_unique(explode(" ", $string2));
$temp = array_intersect($s1, $s2);
var_dump(count($temp) == count($s1) && count($temp) == count($s2));

EDIT

For more than two words here is the snippet,

$string1 = "Perez Perez Pedro";
$string2 = "Perez Pedro Perez";
list($s1,$s2) = [explode(" ", $string1), explode(" ", $string2)];
sort($s1);sort($s2);
var_dump($s1 === $s2);

Working demo.

Yet another approach

$string1 = "Pedro Perez";
$string2 = "Perez Pedro";
$s1 = explode(" ", $string1);
$s2 = explode(" ", $string2);
$comp = empty( array_diff($s1, $s2) ) ? true : false;

The trivial part is to split the strings into words and compare the arrays by size. If the size is not the same, the strings can't be the same:

function str_equals_ignore_word_order(string $str1, string $str2): bool
{
    $words1 = explode(' ', $str1);
    $words2 = explode(' ', $str2);

    if (count($words1) !== count($words2)) {
        return false;
    }

    // Here comes one of the following or already suggested solutions.
}

With that established, we have quite a few of possible solutions for the actual comparison of two arrays of words, which are expected to be in different order.

Already suggested Nr. 1

Sort and compare (simplified without implode):

sort($words1);
sort($words2);

return $words1 === $words2;

This is safe to do and will not change the input as strings are copied when they are passed to a function and we even copied the string into parts when using explode.

Building Dictionaries

Counting the occurences of each word and taking the word count into consideration prevents issues other solutions have with words that occur twice in the input strings. This solution also allows to select different comparisons of the dictionaries:

$words1 = array_count_values($words1);
$words2 = array_count_values($words2);

// Comparison 1
$intersect = array_intersect_assoc($words1, $words2);
return count($intersect) === count($words1) && count($words1) === count($words2);

// Comparison 2
$diff = array_diff_assoc($words1, $words2);
return empty($diff);

Noteworthy

If it's expected that the input contains spelling errors like two spaces right after another ' ', you should use array_filter($words1) on both word arrays to ensure that no NULL words are matched.

A short function for the fun of it, that doesn't sort if necessary.

  • Compare splitted string word count,
  • sort word arrays,
  • compare word arrays.
// Split the sentences, compare word count, sort words, compare sorted words
function compare_words($a, $b) { 
  return count($a = explode(' ', $a)) == count($b = explode(' ', $b)) 
    && sort($a) 
    && sort($b) 
    && $a === $b;
};