Удаление повторяющихся слов в массиве с предложениями в PHP

#php #arrays #unique

#php #массивы #уникальный

Вопрос:

У меня есть массив строк с включенными словами и предложениями.

Например:

 array("dog","cat","the dog is running","some other text","some","text")
  

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

Результат должен выглядеть так:

 array("dog","cat","the is running","other","some","text")
  

Я попробовал array_unique функцию, но она не сработала.

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

1. Добро пожаловать в SO! Каковы ваши требования, по которым дубликаты должны быть удалены? Похоже, что вы предпочитаете сохранять отдельные слова вместо слов в предложениях, но было бы полезно уточнить.

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

3. да, я хотел бы сохранить отдельные слова в массиве, которые являются уникальными.

4. Еще одно продолжение: " " ваш единственный разделитель слов? Все содержимое либо в алфавитном порядке, либо через один пробел?

5. @dWinder спасибо, приятель!! именно то, что я искал

Ответ №1:

Вы можете использовать цикл array_unique after с explode и array_push :

 $res = [];
foreach($arr as $e) {
    array_push($res, ...explode(" ", $e));
}
print_r(array_unique($res));
  

Ссылка:
array_push, explode, array-уникальный

Живой пример: 3v4l

Если вы хотите сохранить предложения, используйте:

 $arr = array("dog","cat","the dog is running","some other text","some","text");

// sort first to get the shortest sentence first
usort($arr, function ($a, $b) {return count(explode(" ", $a)) - count(explode(" ", $b)); });

$words = [];
foreach($arr as amp;$e) {
    $res[] = trim(strtr($e, $words)); //get the word after swapping existing
    foreach(explode(" ", $e) as $w)
        $words[$w] =''; //add all new words to the swapping array with value of empty string
}
  

Ответ №2:

Это решение не очень красивое, но должно выполнить свою работу и удовлетворить некоторые крайние случаи. Я предполагаю, что не более одного пробела разделяет слова в строке предложения и что вы хотите сохранить первоначальный порядок.

Подход заключается в том, чтобы дважды обойти массив, один раз, чтобы отфильтровать повторяющиеся отдельные слова, а затем еще раз, чтобы отфильтровать повторяющиеся слова в предложениях. Это гарантирует приоритет для отдельных слов. Наконец, ksort массив (это уродливая часть с точки зрения временной сложности: все O(max_len_sentence * n) до сих пор).

 $arr = ["dog","cat","the dog is running","some other text","some","text"];
$seen = [];
$result = [];

foreach ($arr as $i => $e) {
    if (preg_match("/^w $/", $e) amp;amp; 
        !array_key_exists($e, $seen)) {
        $result[$i] = $e;
        $seen[$e] = 1;
    }
}

foreach ($arr as $i => $e) {
    $words = explode(" ", $e);

    if (count($words) > 1) {
        $filtered = [];

        foreach ($words as $word) {
            if (!array_key_exists($word, $seen)) {
                $seen[$word] = 0;
            }

            if (  $seen[$word] < 2) {
                $filtered[]= $word;
            }
        } 

        if ($filtered) {
            $result[$i] = implode($filtered, " ");
        }
    }
}

ksort($result);
$result = array_values($result);
print_r($result);
  

Вывод

 Array
(
    [0] => dog
    [1] => cat
    [2] => the is running
    [3] => other
    [4] => some
    [5] => text
)