VaaL2004
@VaaL2004

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

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

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

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

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

Как бы понятно что foreach мне в помощь, меня интересует сам способ сравнения строк. Ведь если сделать strripos, то он сопоставит "Кровать 2-х ярусная (Венге-Дуб Выбеленный)" с "Венге", и это понятно, ведь подстрока "Венге" туда входит, но как сделать так, чтобы он правильно понимал всю эту кашу?
  • Вопрос задан
  • 2425 просмотров
Решения вопроса 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" (Венге)"
}


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

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

Войти через центр авторизации
Похожие вопросы
YCLIENTS Москва
от 200 000 до 350 000 ₽
Ведисофт Екатеринбург
от 25 000 ₽
ИТЦ Аусферр Магнитогорск
от 100 000 до 160 000 ₽
24 апр. 2024, в 20:57
3000 руб./за проект
24 апр. 2024, в 20:35
5000 руб./за проект