2016-04-03 16 views
1

Ich habe dieses Array:Formatierung „Version“ Array Strings nach max len

$versions = [ '1', '1.0.2.4', '1.1.0', '1.12.547.8' ]; 

Und ich will:

$versions = [ '001', '001.000.002.004', '001.001.000', '001.012.547.008' ]; 

Aber, wenn ich dieses:

$versions = [ '1', '1.12' ]; 

Ich will das:

$versions = [ '01', '01.12' ]; 

Mit anderen Worten, jeder String Chunk muss die gleiche Länge von max Chunk len haben.

Erläuterung:

Ich habe ein Array mit variablen Elementen Nummer. Jedes Element ist eine Zeichenfolge aus variablen Zifferngruppen, die durch einen Punkt getrennt sind. Jede Zifferngruppe hat eine variable Länge. Ich möchte, dass alle Array-Untergruppen die gleiche Länge der maximalen Gruppenlänge haben.

Im ersten Beispiel ist die maximale Länge 3 (547), daher haben alle Gruppen des endgültigen Arrays 3 Ziffern (001, 000, ...). Im zweiten Beispiel ist die maximale Länge 2 (12), also haben alle Gruppen 2 Ziffern (01, 01, 12).

Meine Lösung:

$max = max(array_map('strlen', call_user_func_array('array_merge', array_map(function($row) { return explode('.', $row); }, $versions)))); 
foreach($versions as &$version) 
{ 
    $version = preg_replace('/\d*(\d{'.$max.'})/', '\1', preg_replace('/(\d+)/', str_repeat('0', $max).'\1', $version)); 
} 

Erklärt:

$tmp = array_map(function($row) { return explode('.', $row); }, $versions); 
$tmp = call_user_func_array('array_merge', $tmp); 
$tmp = array_map('strlen', $tmp); 
$max = max($tmp); 

$tmp = preg_replace('/(\d+)/', str_repeat('0', $max).'\1', $version); 
$version = preg_replace('/\d*(\d{'.$max.'})/', '\1', $tmp); 

Jemand eine Idee haben, den Prozess zu vereinfachen?

+0

hat Ihr Array nur Ziffern und Punkte enthalten? Sie können dies ohne Regex tun, indem Sie eine formatierte Zeichenfolge verwenden. –

+0

Trennzeichen nur Punkte. Untergruppen alphanumerisch. – LVA

+0

alphanumerisch? Du meinst, du kannst '1.1.0a' haben? –

Antwort

5

Nun kann man einfach alles vereinfachen, was Sie bereits getan:

Zuerst haben wir das Array in einen String implode() können und alle Zahlen übereinstimmen mit preg_match_all().

Um dann die längste Nummer zu bekommen, benutzen wir einfach array_map() mit strlen() als Rückruf und bekommen die längste Nummer mit max().

Wenn Sie Ihre Padlänge kennen, können Sie Ihr Array mit preg_replace_callback() durchsuchen und Ihre Nummern mit str_pad() auffüllen.

Code:

<?php 

    $versions = [ '1', '1.0.2.4', '1.1.0', '1.12.547.8' ]; 

    preg_match_all("/\d+/", implode(".", $versions), $m); 
    $max = max(array_map("strlen", $m[0])); 

    $new = preg_replace_callback("/(\d+)/", function($m)use($max){ 
     return str_pad($m[1], $max, "0", STR_PAD_LEFT); 
    }, $versions); 

    print_r($new); 

?>