Как перебрать большой массив на 60000 строк?

76
21 сентября 2021, 00:00
public function synonimize(){
    $str = 'Кроткий и квелый карлик Андрюха качнулся и кинулся на Андриана, что он не работает';
    $words = $this->getWords();
    $result = $this->getRandomText($str, $words);
    dd($result);
}
protected function getRandomText($str, $words){
    mb_internal_encoding("UTF-8");
    $repl_array = $words;
    $keys = array_map(function($key){
        return '#'.$key.'#ui';
    }, $repl_array);
    foreach ($keys as $i=>$key) {
        $str = preg_replace_callback($key, function ($match) use ($repl_array, $i) {
            $syns = explode('|', $repl_array[$i]);
            array_splice($syns, array_search(mb_strtolower($match[0]), array_map('mb_strtolower', $syns)), 1);
            return $syns[rand(0, count($syns) - 1)];
        }, $str);
    }
    return $str;
}

protected function getWords(){
    $arr = [
        "Fora|фора",
        "Ford|форд",
        "General motors|дженерал моторс",
        "Google|гугл",
        "Hand|хэнд",
        "Hi-tech|хай-тек",
        "Homo sapiens|человек разумный",
        "Hyundai|хэндэ",
        "Ip-адрес|айпишник",
        "Ясного представления|четкого понятия",
        "Ясное понятие|четкое представление",
        "Ясное представление|четкое понятие",
        "Ясному представлению|четкому понятию",
         ......... 
         и еще много строк
    ];
    return $arr;
}

на пк если запустить такой скрипт то комп очень долго думает возможно например етот код залить на VPS сервак чтобы он быстро ответ давал, или что-то еще чтобы ускорить работу foreach?

Answer 1

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

Самое простое, что можно придумать:

  1. Разбиваем массив words на отдельные строки для каждого синонима с указателем на всю цепочку, затем эти строки помещаем в общий массив с ключем по первому слову
  2. Разбиваем исходную строку на слова
  3. Ищем эти слова в массиве.
  4. Если нашли, то сравниваем остальную часть фразы.
  5. Если фраза совпала, то выбираем синоним.

В коде первый пункт выглядит как-то так

function getWords() {
  $res = [
    'words' => [],
    'syns' => [
      ['Fora', 'фора'],
      ['Ford', 'форд'],
      ['General motors', 'дженерал моторс'],
      ['Google', 'гугл'],
      ['Homo sapiens', 'человек разумный'],
    ]
  ];
  foreach ($res['syns'] as $idx => &$set) {
    foreach ($set as &$syn) {
      $syn = mb_strtolower($syn);
      $words = explode(' ', $syn);
      $word = $words[0];
      if (!isset($res['words'][$word]))
        $res['words'][$word] = [];
      $res['words'][$word][] = [
        'phrase' => $words,
        'idx' => $idx
      ];
    }
  }
  return $res;
}
READ ALSO
Как получить значение тега из SimpleXMLElement?

Как получить значение тега из SimpleXMLElement?

Как получить значение тега <category> и записать его в масив?

101
Как подключать стили в php?

Как подключать стили в php?

Я новичок в phpСоздал папку в которой 2 файла - index

74
Не работает запрос UPDATE php

Не работает запрос UPDATE php

Не работает запрос UPDATE, данные не изменяютсяПеременные существуют, через echo проверял, подключение к базе данных тоже, другие запросы выполняются

80
Как бороться с Segmentation fault?

Как бороться с Segmentation fault?

Выполняю скрипт примерно такого содержания:

253