удалить дубликат из строки в PHP


Я ищу самый быстрый способ удалить повторяющиеся значения в строке, разделенной запятыми.

Итак, моя строка выглядит так;

$str = 'one,two,one,five,seven,bag,tea';

Я могу сделать это, разбив строку на значения, а затем сравнить, но я думаю, что это будет медленно. как насчет preg_replace() будет ли это быстрее? Кто-нибудь делал это с помощью этой функции?

Author: Adnan, 2010-04-10

2 answers

Самый короткий код будет:

$str = implode(',',array_unique(explode(',', $str)));

Если это самый быстрый... Я не знаю, это, вероятно, быстрее, чем явный цикл.

Ссылка: implode, array_unique, explode

 112
Author: Felix Kling, 2010-04-10 10:41:47

Работа с: $string = 'one,two,one,five,seven,bag,tea';

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

Допустим, вы используете конкатенацию для создания строки, например:

$string='';
foreach($data as $value){
    $string.=(strlen($string)?',':'').some_func($value);
}

...затем вам нужно будет извлечь уникальные значения из $string на основе разделителя (запятая), а затем повторно использовать разделитель.


Я предлагаю вам разработать более прямой метод и запретить дубликаты внутри начальный цикл для каждого, например:

foreach($data as $value){
    $return_value=some_func($value);  // cache the returned value so you don't call the function twice
    $array[$return_value]=$return_value;  // store the return value in a temporary array using the function's return value as both the key and value in the array.
}
$string=implode(',',$array);  // clean: no duplicates, no trailing commas

Это работает, потому что повторяющимся значениям никогда не разрешается существовать. Все последующие вхождения будут использоваться для перезаписи более раннего вхождения. Этот фильтр без функций работает, потому что массивы могут не иметь двух одинаковых ключей в одном массиве (уровне).

В качестве альтернативы вы можете избежать "перезаписи" данных массива в цикле, вызвав if(!isset($array[$return_value])){$array[$return_value]=$return_value;}, но разница означает вызов функции isset() на каждой итерации. Преимущество использования эти ассоциативные назначения ключей заключаются в том, что процесс избегает использования in_array(), которое медленнее, чем isset().

Все сказанное, если вы извлекаете столбец данных из 2-мерного массива, например:

$string='';
foreach($data as $value){
    $string.=(strlen($string)?',':'').$value['word'];
}

Тогда вы могли бы использовать магию array_column() без цикла , как это:

echo implode(',',array_column($str,'word','word'));

И, наконец, для тех, кто интересуется микрооптимизацией, я отмечу, что один вызов array_unique() на самом деле медленнее, чем несколько методов с двумя функциями. Читать здесь для более подробной информации.

Суть в том, что есть много способов выполнить эту задачу. explode->unique->implode может быть наиболее кратким методом в некоторых случаях, если вы не генерируете строку с разделителями, но вряд ли это будет самый прямой или быстрый метод. Выберите для себя то, что лучше всего подходит для вашей задачи.

 0
Author: mickmackusa, 2018-02-01 02:46:34