2015-07-02 35 views
12

Sto provando a normalizzare una stringa di numeri separati da virgola e anche un intervallo. Per dimostrare:PHP: inserire una matrice in un altro array

la matrice:

$array = ["1","2","5-10","15-20"]; 

dovrebbe diventare:

$array = [1,2,5,6,7,8,9,10,15,16,17,18,19,20]; 

L'algoritmo su cui sto lavorando è:

//get the array values with a range in it : 
$rangeArray = preg_grep('[-]',$array); 

Questo conterrà ["5-10", "16-20"]; Poi:

foreach($rangeArray as $index=>$value){ 
    $rangeVal = explode('-',$value); 
    $convertedArray = range($rangeVal[0],$rangeVal[1]); 
} 

L'array convertito ora conterrà ["5", "6", "7", "8", "9", "10"];

Il problema che ora ad affrontare è che, come faccio a saltar fuori il valore "5-10" nella matrice originale, e inserire i valori nella $ convertedArray, in modo che avrò il valore:

$ array = ["1", "2", "5", "6", "7", "8", "9", "10", "16-20"];

Quindi, come si inserisce una matrice in una matrice? O c'è un modo più pulito per risolvere questo tipo di problema? convertire l'array di numeri e valori di intervallo in array di numeri correttamente sequenziati?

+2

[array_splice()] (http://www.php.net/manual/en/function.array-splice.php) è la funzione che stai chiedendo, anche se si potrebbe anche usare [array_merge()] (http://www.php.net/manual/en/function.array-merge.php) se non ti interessa l'ordine delle voci –

+0

potresti fornire un esempio su come potrei usarlo in il mio caso? – muffin

+0

ho provato l'unione matrice, ma poi avrei dovuto eliminare quelli con "5-10" e altri valori di intervallo e quindi inserire i valori "normalizzati" nell'indice di quella stringa di intervallo. – muffin

risposta

4

Prova questa:

<?php 
$array = ["1","2","5-10","15-20"]; 

$newdata = array(); 
foreach($array as $data){ 
    if(strpos($data,'-')){ 

     $range = explode('-', $data); 
     for($i=$range[0];$i<=$range[1];$i++){ 
      array_push($newdata, $i); 
     } 
    } 
    else{ 
     array_push($newdata, (int)$data); 
    } 

} 

     echo "<pre>"; 
print_r($array); 
     echo "</pre>"; 
     echo "<pre>"; 
print_r($newdata); 
     echo "</pre>"; 

Risultato:

Array 
(
    [0] => 1 
    [1] => 2 
    [2] => 5-10 
    [3] => 15-20 
) 
Array 
(
    [0] => 1 
    [1] => 2 
    [2] => 5 
    [3] => 6 
    [4] => 7 
    [5] => 8 
    [6] => 9 
    [7] => 10 
    [8] => 15 
    [9] => 16 
    [10] => 17 
    [11] => 18 
    [12] => 19 
    [13] => 20 
) 

Problema risolto!

2

Risposta più semplice e più breve.

See in Ideone

$new_array = array(); 

foreach($array as $number){ 
    if(strpos($number,'-')){ 
    $range = explode('-', $number); 
    $new_array = array_merge($new_array, range($range[0],$range[1])); 
    } 
    else{ 
    $new_array[] = (int) $number; 
    } 
} 

var_dump($new_array); 
+0

quello che fa è: ["1", "2", array(), array()]; – muffin

+0

anche la demo è sbagliata ... se si guarda l'indice 2 dell'array originale, contiene un altro array al suo interno. – muffin

+0

@muffin Aggiornato, dai un'occhiata. – Muhammet

2

Utilizzando gamma e array_merge per gestire i valori non numerici:

$array = ["1","2","5-10","15-20"]; 

$newArray = []; 
array_walk(
    $array, 
    function($value) use (&$newArray) { 
     if (is_numeric($value)) { 
      $newArray[] = intval($value); 
     } else { 
      $newArray = array_merge(
       $newArray, 
       call_user_func_array('range', explode('-', $value)) 
      ); 
     } 
    } 
); 

var_dump($newArray); 
3

Qui si va. Ho provato a ridurre al minimo il codice il più possibile.

Si consideri la matrice iniziale di seguito,

$array = ["1","2","5-10","15-20"]; 

Se si desidera creare un nuovo array fuori di esso, invece $array, il cambiamento al di sotto della prima occorrenza di $array a qualsiasi nome che si desidera,

$array = call_user_func_array('array_merge', array_map(function($value) { 
      if(1 == count($explode = explode('-', $value, 2))) { 
       return [(int)$value]; 
      } 
      return range((int)$explode[0], (int)$explode[1]); 
     }, $array)); 

Ora, il $array diventa,

$array = [1,2,5,6,7,8,9,10,15,16,17,18,19,20]; 

Note:

  • getta ogni membro trasformata a intero
  • Se è previsto 15-20-25, prende 15-20 in considerazione e ignora il resto
  • Se 15a-20b è previsto, trattato come 15-20, questo è risultato intelaiatura a numero intero dopo esploso con -, 15a diventa 15
  • Casella i tasti della matrice in ordine crescente numerico a partire da fr om 0
  • nuovo array è ordinato solo se dato array è in ordine crescente di singoli membri e dei gamma combinata
2

È più facile trovare il valore minimo e massimo e creare l'array con loro. Ecco un esempio:

$in = ["1","2","5-10","15-20"]; 
$out = normalizeArray($in); 
var_dump($out); 

function normalizeArray($in) 
{ 
    if(is_array($in) && sizeof($in) != 0) 
    { 
     $min = null; 
     $max = null; 
     foreach($in as $k => $elem) 
     { 
      $vals = explode('-', $elem); 
      foreach($vals as $i => $val) 
      { 
       $val = intval($val); 
       if($min == null || $val < $min) 
       { 
        $min = $val; 
       } 
       if($max == null || $val > $max) 
       { 
        $max = $val; 
       } 
      } 
     } 

     $out = array(); 
     for($i = $min; $i <= $max; $i++) 
     { 
      $out[] = $i; 
     } 

     return $out; 
    } 
    else 
    { 
     return array(); 
    } 
} 
1

provare questo:

$array = ["1","2","5-10","15-20"]; 
$result = []; 

foreach ($array as $a) { 
    if (strpos($a,"-")!== false){ 
     $tmp = explode("-",$a); 
     for ($i = $tmp[0]; $i<= $tmp[1]; $i++) $result[] = $i; 
    } else { 
     $result[] = $a; 
    } 
} 

var_dump($result); 
0

voi non ha finito un po '

$array = ["1","2","5-10","15-20"]; 
// need to reverse order else index will be incorrect after inserting 
$rangeArray = array_reverse(preg_grep('[-]',$array), true); 

$convertedArray = $array; 

foreach($rangeArray as $index=>$value) { 

    $rangeVal = explode('-',$value); 
    array_splice($convertedArray, $index, 1, range($rangeVal[0],$rangeVal[1])); 
} 

print_r($convertedArray); 
2

qui si va compagno.

<?php 
$array = ["1","2","5-10","15-20"]; 
$newArr = array(); 
foreach($array as $item){ 
    if(strpos($item, "-")){ 
     $temp = explode("-", $item); 
     $first = (int) $temp[0]; 
     $last = (int) $temp[1]; 
     for($i = $first; $i<=$last; $i++){ 
      array_push($newArr, $i); 
     } 
    } 
    else 
     array_push($newArr, $item); 
} 
print_r($newArr); 
?>