array_uintersect с вложенными массивами не пересекается с первым элементом

#php #arrays #set #intersection #built-in

Вопрос:

Я создал следующий скрипт для создания array_uintersect алогритма.

 function compare2D($topic, $nomination): int
{
    if (is_array($nomination)) {
        return in_array($topic, $nomination) ? 0 : 1;
    }
    else if (is_array($topic)) {
            return in_array($nomination, $topic) ? 0 : 1;
    }

    return strcmp($topic, $nomination);
}

$arr  = [['REMOTE', 'REMOTE_PREMIUM'], 'SECURE'];
$topic = ['SECURE', 'REMOTE'];


var_dump(array_uintersect($topic, $arr, 'compare2D'));
 

Когда я запускаю его, результат таков

 array(1) {
  [0] =>
  string(6) "SECURE"
}
 

Куда он должен возвращаться

 array(2) {
  [0] =>
  string(6) "SECURE"
  [1] =>
  string(6) "REMOTE"
}

 

Я обнаружил, что это зависит только от массива во 2-м аргументе для _uintersect наличия подмассива с индексом 0 (первый элемент).
Когда я перемещаю подмассив в любую позицию, кроме 1-й, то есть:

 $arr  = ['SECURE', ['REMOTE', 'REMOTE_PREMIUM']];
// or
$arr  = ['SOMEVALUE', ['REMOTE', 'REMOTE_PREMIUM'], 'SECURE'];
 

…пересечение работает нормально, и я получаю желаемый результат выше.

Кто-нибудь знает некоторые алгоритмические правила пересечения php, о которых я не знаю?

Комментарии:

1. Просто попробовал код и получил array(2) { [0] => string(4) "PLUM" [1] => string(9) "RASPBERRY" }

2. О, подожди, я тоже почесал голову . Я включил здесь запутанные строки, но детали не настолько чувствительны, поэтому я немедленно изменю их обратно

3. @NigelRen Вернулся к реальным строкам, может попробовать еще раз

4. Все зависит от того , с чего вы возвращаетесь return in_array($topic, $nomination) ? 0 : 1; , зависит от того, какие строки вы вставляете, это может сработать, а может и не сработать. К сожалению, у меня нет времени на дальнейшие расследования. (см. php.net/manual/en/function. массив-uintersect.php#72841 )

Ответ №1:

Я думаю, что вы можете переключить логику возврата 1 и 0, поэтому возвращайте 1, когда значение находится в массиве, так как вы хотите найти пересечение.

В последней части использование strcmp вернет 0, если строки равны. В этом случае вы можете проверить, равны ли они, и если да, то верните 1.

 function compare2D($topic, $nomination): int
{
    if (is_array($nomination)) {
        return in_array($topic, $nomination) ? 1 : 0;
    }
    if (is_array($topic)) {
        return in_array($nomination, $topic) ? 1 : 0;
    }
    
    return strcmp($topic, $nomination) === 0 ? 1 : 0;
}

$topic = ['SECURE', 'REMOTE'];
$arr  = [['REMOTE', 'REMOTE_PREMIUM'], 'SECURE'];

$res = array_uintersect($topic, $arr, 'compare2D');
var_dump($res);
 

Выход

 array(2) {
  [0]=>
  string(6) "SECURE"
  [1]=>
  string(6) "REMOTE"
}
 

Демонстрация Php | Демонстрация Php с большим количеством вложенных массивов

Комментарии:

1. Спасибо за ответ — значит, вы хотите сказать, что я должен просто инвертировать свои ответы, и это сработает? Согласно вашим демо-записям, похоже, что вы заставили его работать именно так. Это странно, потому что в uintersect документах php php.net/manual/en/function. array-uintersect.php#72841 это показывает, что вы можете просто подключиться, strcmp и возврат по умолчанию будет работать для пересечения 1D массивов. В любом случае, кто я такой, чтобы спорить с вашими результатами!

2. @ScottAnderson Я провел несколько тестов, и, похоже, получил желаемые результаты. У меня также был другой вариант, чтобы сравнивать строки только в том случае, если оба параметра не являются массивом. Это дает ожидаемые результаты, но вы могли бы провести еще несколько тестов, чтобы убедиться, что он ничего не пропустил. Видишь 3v4l.org/qJeuI