Задать вопрос
VaaL2004
@VaaL2004

Как правильно сопоставить массивы?

Здравствуйте, подскажите пожалуйста, как правильно сделать сравнение.
Имеется примерно такой массив:

Кровать 2-х ярусная (Венге-Дуб Выбеленный)
Полка "ПН-1" (Венге)
Полка "ПН-4" (Венге светлый)
и далее много подобного...

Также имеется массив материалов:
Венге
Венге+дуб выбеленный
Венге темный
Венге светлый
Венге светлый+темный

Как правильно сопоставить эти массивы?

Как бы понятно что foreach мне в помощь, меня интересует сам способ сравнения строк. Ведь если сделать strripos, то он сопоставит "Кровать 2-х ярусная (Венге-Дуб Выбеленный)" с "Венге", и это понятно, ведь подстрока "Венге" туда входит, но как сделать так, чтобы он правильно понимал всю эту кашу?
  • Вопрос задан
  • 2425 просмотров
Подписаться 2 Оценить Комментировать
Решения вопроса 1
alexclear
@alexclear
A cat
При сравнении с массивом названий материалов нужно идти от более специфичных строк к менее специфичным.
Если одна строка с названием материала входит в другую строку с названием материала же, то она менее специфична, и ее надо проверять в последнюю очередь.
Таким образом, нужно сперва правильно отсортировать массив строк с названиями материалов, с котором ведется сравнение, а потом уже с ним сравнивать.
Как вариант - сначала сделать сравнение со всем массивом материалов и найти все совпадения, а потом уже выбрать из них наиболее специфичное.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Можно попробовать поплясать с функцией similar_text

Если в первом массиве всегда в скобках пишутся значения, которые содержатся во втором массиве - то есть смысл из первого массива сравнивать только то что в скобках.

Алгоритм примерно такой:

$fullNames = [
    'Кровать 2-х ярусная (Венге-Дуб Выбеленный)',
    'Полка "ПН-1" (Венге)',
    'Полка "ПН-4" (Венге светлый)'
];
   
$shortNames = [
    "Венге",
    "Венге+дуб выбеленный",
    "Венге светлый"
];

function getTextBeetwenBraces($text) {
    $firstBracePos = strrpos($text, '(');
    $lastBracePos = strrpos($text, ')');
    $betweenBraces = substr($text,  $firstBracePos + 1, $lastBracePos - $firstBracePos - 1);

    return $betweenBraces;
}

usort($fullNames, function($a, $b) {
    return strlen(getTextBeetwenBraces($b)) - strlen(getTextBeetwenBraces($a));
});

usort($shortNames, function($a, $b) {
    return strlen($b) - strlen($a);
});

$result = [];
for ($i = 0, $j = count($fullNames); $i < $j; ++$i) {
    $ranks = [];

    for ($l = $i, $k = count($shortNames); $l < $k; ++$l) {
        $ranks[similar_text($fullNames[$i], $shortNames[$l])] = $l;
    }

    ksort($ranks);

    $result[$shortNames[end($ranks)]] = $fullNames[$i];
}

var_dump($result);


Результат:

array(3) {
  ["Венге+дуб выбеленный"]=>
  string(75) "Кровать 2-х ярусная (Венге-Дуб Выбеленный)"
  ["Венге светлый"]=>
  string(47) "Полка "ПН-4" (Венге светлый)"
  ["Венге"]=>
  string(32) "Полка "ПН-1" (Венге)"
}


Это всего-лишь примерный код, его можно совершенствовать под конкретные случаи. Но мне кажется это работает)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы