web-dev-qa-db-fra.com

Exploser qui ne renvoie pas de chaînes vides?

La fonction d'explosion de PHP renvoie un tableau de chaînes réparties sur certaines sous-chaînes fournies. Il retournera des chaînes vides comme ceci:

var_dump(explode('/', '1/2//3/'));
array(5) {
  [0]=>
  string(1) "1"
  [1]=>
  string(1) "2"
  [2]=>
  string(0) ""
  [3]=>
  string(1) "3"
  [4]=>
  string(0) ""
}

Y at-il une fonction différente ou une option ou quelque chose qui renverrait tout sauf les chaînes vides?

var_dump(different_explode('/', '1/2//3/'));
array(3) {
  [0]=>
  string(1) "1"
  [1]=>
  string(1) "2"
  [2]=>
  string(1) "3"
}
29
Glenn Moss

Essayez preg_split .

$exploded = preg_split('@/@', '1/2//3/', NULL, PREG_SPLIT_NO_EMPTY);

56
ceejayoz

array_filter va supprimer les champs vides, voici un exemple sans le filtre:

print_r(explode('/', '1/2//3/'))

impressions:

Array
(
    [0] => 1
    [1] => 2
    [2] =>
    [3] => 3
    [4] =>
)

Avec le filtre:

php> print_r(array_filter(explode('/', '1/2//3/')))

Impressions:

Array
(
    [0] => 1
    [1] => 2
    [3] => 3
)

Vous obtiendrez toutes les valeurs résolues en "faux" filtrées.

voir http://fr.php.net/manual/en/function.array-filter.php

19
Dave Gregory

Juste pour la variété:

array_diff(explode('/', '1/2//3/'), array(''))

Cela fonctionne aussi, mais gache les index de tableau contrairement à preg_split. Certaines personnes aimeraient peut-être mieux que de devoir déclarer une fonction de rappel pour utiliser array_filter.

6
Glenn Moss
function not_empty_string($s) {
  return $s !== "";
}

array_filter(explode('/', '1/2//3/'), 'not_empty_string');
4
James Aylett

Voici une solution qui devrait générer un tableau nouvellement indexé.

$result = array_deflate( explode( $delim, $array) );

function array_deflate( $arr, $emptyval='' ){
    $ret=[];
    for($i=0,$L=count($arr); $i<$L; ++$i)
        if($arr[$i] !== $emptyval) $ret[]=$arr[$i];
    return $ret;
}

Bien que assez similaire à une autre suggestion, cette mise en œuvre présente l'avantage d'une utilisation générique. Pour les tableaux contenant des éléments autres que des chaînes, indiquez une valeur vide typée comme deuxième argument.

array_deflate( $objArray, new stdClass() );

array_deflate( $databaseArray, NULL );

array_deflate( $intArray, NULL );

array_deflate( $arrayArray, [] );

array_deflate( $assocArrayArray, [''=>NULL] );

array_deflate( $processedArray, new Exception('processing error') );

.

.

.

Avec un argument de filtre optionnel ..

function array_deflate( $arr, $trigger='', $filter=NULL, $compare=NULL){
    $ret=[];
    if ($filter === NULL) $filter = function($el) { return $el; };
    if ($compare === NULL) $compare = function($a,$b) { return $a===$b; };

    for($i=0,$L=count($arr); $i<$L; ++$i)
        if( !$compare(arr[$i],$trigger) ) $ret[]=$arr[$i];
        else $filter($arr[$i]);
    return $ret;
}

Avec l'usage ..

function targetHandler($t){ /* .... */ }    
array_deflate( $haystack, $needle, targetHandler );

Transformer array_deflate en une manière de traiter les éléments de choix et de les supprimer de votre tableau. Il est également plus agréable de transformer l’instruction if en une fonction de comparaison qui est également transmise en tant qu’argument au cas où vous en auriez envie.

array_inflate étant l'inverse, prendrait un tableau supplémentaire comme premier paramètre auquel les correspondances sont poussées tandis que les non-correspondances sont filtrées.

function array_inflate($dest,$src,$trigger='', $filter=NULL, $compare=NULL){
    if ($filter === NULL) $filter = function($el) { return $el; };
    if ($compare === NULL) $compare = function($a,$b) { return $a===$b; };

    for($i=0,$L=count($src); $i<$L; ++$i)
        if( $compare(src[$i],$trigger) ) $dest[]=$src[$i];
        else $filter($src[$i]);
    return $dest;
}

Avec l'usage ..

$smartppl=[];    
$smartppl=array_inflate( $smartppl,
                         $allppl,
                         (object)['intelligence'=>110],
                         cureStupid,
                         isSmart);

function isSmart($a,$threshold){
    if( isset($a->intellgence) )    //has intelligence?
        if( isset($threshold->intellgence) )    //has intelligence?
            if( $a->intelligence >= $threshold->intelligence )
                return true;
            else return INVALID_THRESHOLD; //error
        else return INVALID_TARGET; //error
    return false;
}

function cureStupid($person){
    $dangerous_chemical = selectNeurosteroid();
    applyNeurosteroid($person, $dangerous_chemical);

    if( isSmart($person,(object)['intelligence'=>110]) ) 
        return $person;
    else 
        lobotomize($person);

    return $person;
}

Fournissant ainsi un algorithme idéal pour les problèmes éducatifs du monde. Aaand, je vais m'arrêter là avant de modifier quelque chose d'autre.

1
Garet Claborn

J'ai utilisé cela dans TYPO3 , regardez le paramètre $onlyNonEmptyValues:

function trimExplode($delim, $string, $onlyNonEmptyValues=0){
    $temp = explode($delim,$string);
    $newtemp=array();
    while(list($key,$val)=each($temp))      {
        if (!$onlyNonEmptyValues || strcmp("",trim($val)))      {
            $newtemp[]=trim($val);
        }
    }
    reset($newtemp);
    return $newtemp;
}

Cela ne gâche pas les index:

var_dump(trimExplode('/', '1/2//3/',1));

Résultat:

array(3) {
  [0]=>
  string(1) "1"
  [1]=>
  string(1) "2"
  [2]=>
  string(1) "3"
}
1
Memochipan

Ecrivez une fonction wrapper pour les déshabiller

function MyExplode($sep, $str)
{
    $arr = explode($sep, $str);
    foreach($arr as $item)
        if(item != "")
            $out[] = $item;
    return $out;
}
0
Fire Lancer

Je n'ai pas testé les autres suggestions ici, mais cela fonctionne:

function different_explode($mypattern,$mystring){
    $array1 = explode($mypattern,$mystring);
    $retArray = Array();
    foreach($array1 as $myval){
        if($myval != ''){
            array_Push($retArray,$myval);
        }
    }
    return $retArray;
}
0
Derek Kurth

Les solutions d'expression régulière ont tendance à être beaucoup plus lentes que le remplacement de texte de base, aussi je remplacerais les séparateurs doubles par des séparateurs simples, couperais la chaîne de tout espace, puis utiliserait exploser

// assuming $source = '1/2//3/';
$source = str_replace('//', '/', $source);
$source = trim($source);
$parts = explode('/', $source);
0
Adam Hopkinson

Pas de surcharge de regex - devrait être raisonnablement efficace, strlen ne compte que les octets

Supprimez les valeurs array_values ​​() si vous ne vous souciez pas des index

Faites-en une fonction explode_interesting ($ array, $ fix_index = 0) si vous voulez

$interesting = array_values( 
                 array_filter(
                   explode('/', '/1//2//3///4/0/false' ),
                   function ($val) { return strlen($val); }
               ));

echo "<pre>", var_export( $interesting, true ), "</pre>";

profiter, Jeff

0
Jeff

Utilisez cette fonction pour filtrer la sortie de la fonction d'exploser

  function filter_empty(&$arrayvar) {
        $newarray = array();
        foreach ($arrayvar as $k => $value)
            if ($value !== "")
                $newarray[$k] = $value;

        $arrayvar = $newarray;
    }
0
AntonioCS