2016-06-16 10 views
5

Ich möchte mehrere Arrays zusammenführen, während die Werte aus dem ersten Array bevorzugt werden und nur eindeutige Werte haben. Gibt es einen schnelleren Weg als array_merge(), array_unique() und den Operator +?PHP array_merge() mit der Präferenz des ersten Arrays und nur eindeutige Werte?

function foo(...$params) { 
    $a = [ 
     'col1', 
     'col2_alias' => 'col2', 
     'col3' 
    ]; 
    $merged = array_merge($a, ...$params); 
    $unique = array_unique($merged); 
    print_r($merged); 
    print_r($unique); 
    print_r($a + $unique); 
} 

foo(
    ['col4', 'col5_alias' => 'col5', 'col6'], 
    ['col7', 'col1', 'col5_alias' => 'col5', 'col2_alias' => 'col10']); 

einfach die Arrays Verschmelzung gibt mir Werte duplizieren, und überschreibt Werte in der ersten Reihe:

Array 
(
    [0] => col1 // duplicate 
    [col2_alias] => col10 // overwritten 
    [1] => col3 
    [2] => col4 
    [col5_alias] => col5 
    [3] => col6 
    [4] => col7 
    [5] => col1 // duplicate 
) 

Mit array_unique() offensichtlich die doppelten Werte fixiert, aber nicht die überschriebene Wert:

Array 
(
    [0] => col1 
    [col2_alias] => col10 
    [1] => col3 
    [2] => col4 
    [col5_alias] => col5 
    [3] => col6 
    [4] => col7 
) 

Nach der Verwendung des +-Operators ist das Array, wie ich es will.

+0

Möchten Sie eine Sammlung Bibliothek in Betracht ziehen? –

+1

Was ist schlecht in + Operator, wenn es funktioniert? Ist es langsam? – instead

+0

@ ÁlvaroGuimarães Leider ist es in Legacy-Code, und das Hinzufügen einer Sammlung Bibliothek wäre ein Ärger. – GreeKatrina

Antwort

0

Sie haben recht, wenn Sie davon ausgehen, dass die Verwendung der Funktionen array_merge, array_unique und + langsam ist. Und ich habe die Geschwindigkeit jeder Kombination ein Stück Code zu Benchmark geschrieben ...

Hier der Code ist ...

<?php 

class ArraySpeeds 
{ 
    public $la = ['col1', 'col2_alias' => 'col2', 'col3']; 
    public $a = ['col4', 'col5_alias' => 'col5', 'col6']; 
    public $b = ['col7', 'col1', 'col5_alias' => 'col5', 'col2_alias' => 'col10']; 
    public $c = []; 

    public function executionTime ($callback) 
    { 
     $start = microtime (true); 

     for ($i = 0; $i < 1000000; $i++) { 
      $callback(); 
     } 

     return round ((microtime (true) - $start) * 1000) . '/ms' . PHP_EOL; 
    } 

    public function getTimes() 
    { 
     $array_merge_time = $this->executionTime (function() { 
      $this->c[0] = array_merge ($this->la, $this->a, $this->b); 
     }); 

     $array_unique_time = $this->executionTime (function() { 
      $merged = array_merge ($this->la, $this->a, $this->b); 
      $this->c[1] = array_unique ($merged); 
     }); 

     $addition_time = $this->executionTime (function() { 
      $merged = array_merge ($this->la, $this->a, $this->b); 
      $unique = array_unique ($merged); 
      $this->c[2] = $this->la + $unique; 
     }); 

     $array_diff_time = $this->executionTime (function() { 
      $merged = array_merge ($this->a, $this->b); 
      $diffed = array_diff ($merged, $this->la); 

      $this->c[3] = array_merge ($diffed, $this->la); 
     }); 

     echo print_r ($this->c[0], true), PHP_EOL; 
     echo print_r ($this->c[1], true), PHP_EOL; 
     echo print_r ($this->c[2], true), PHP_EOL; 

     natsort ($this->c[3]); 
     echo print_r ($this->c[3], true), PHP_EOL; 

     echo 'array_merge: ', $array_merge_time; 
     echo 'array_unique: ', $array_unique_time; 
     echo 'addition: ', $addition_time; 
     echo 'array_diff: ', $array_diff_time; 
    } 
} 

$arrayspeeds = new ArraySpeeds(); 
$arrayspeeds->getTimes(); 

Dies ist der Ausgang ...

Array 
(
    [0] => col1 
    [col2_alias] => col10 
    [1] => col3 
    [2] => col4 
    [col5_alias] => col5 
    [3] => col6 
    [4] => col7 
    [5] => col1 
) 

Array 
(
    [0] => col1 
    [col2_alias] => col10 
    [1] => col3 
    [2] => col4 
    [col5_alias] => col5 
    [3] => col6 
    [4] => col7 
) 

Array 
(
    [0] => col1 
    [col2_alias] => col2 
    [1] => col3 
    [2] => col4 
    [col5_alias] => col5 
    [3] => col6 
    [4] => col7 
) 

Array 
(
    [3] => col1 
    [col2_alias] => col2 
    [4] => col3 
    [0] => col4 
    [col5_alias] => col5 
    [1] => col6 
    [2] => col7 
) 

array_merge: 403/ms 
array_unique: 1039/ms 
addition: 1267/ms 
array_diff: 993/ms 

Sie können sehen, dass die Ausführungszeit bei jedem hinzugefügten Funktionsaufruf länger wird, wobei die array_merge, array_unique Funktionen und + die langsamste, mehr als doppelt so langsame Operation sind.

Mit array_diff erhalten Sie jedoch eine anständige Leistung mit der richtigen Ausgabe, aber ohne korrekte Sortierung. Das Hinzufügen eines Funktionsaufrufs natsort zu dem Array würde das beheben.

Zum Beispiel ...

function foo (...$params) 
{ 
    $a = [ 
     'col1', 
     'col2_alias' => 'col2', 
     'col3' 
    ]; 

    $diff = array_diff (array_merge (...$params), $a); 
    $merged = array_merge ($diff, $a); 
    natsort ($merged); 
    print_r ($merged); 
} 
+0

Ich brauche sie nicht sortiert werden, so funktioniert das perfekt, danke! – GreeKatrina

+0

Ich habe diese Antwort gewählt, aber aus irgendeinem Grund zeigt es immer noch Null. Wenn Sie die Rep-Punkte nicht erhalten haben, lassen Sie SO davon wissen. – GreeKatrina

1

Eigentlich sehe ich keine größeren Probleme mit Ihrem Skript und ich weiß nicht, warum Sie es verbessern möchten. Aber ich habe meine Umsetzung Ihrer Funktion geschrieben und es scheint, dass es ein wenig schneller arbeitet, einen Blick (ich habe auch ein paar mehr params zusätzliche Funktion Ergebnisse zu testen):

<?php 

function foo(...$params) { 
    $a = [ 
     'col1', 
     'col2_alias' => 'col2', 
     'col3' 
    ]; 
    $merged = array_merge($a, ...$params); 
    $unique = array_unique($merged); 

    return $a + $unique; 
} 

function foo2(...$params) { 
    $a = [ 
     'col1', 
     'col2_alias' => 'col2', 
     'col3' 
    ]; 
    $merged = array_merge(array_diff(array_merge(...$params), $a), $a); 

    return $merged; 
} 

$timeFoo = microtime(true); 
for($i = 0; $i < 1000000; $i++) { 
    foo(
    ['col13', 'col5_alias' => 'col3', 'col8'], 
    ['col21', 'col5_alias' => 'col1', 'col9'], 
    ['col4', 'col5_alias' => 'col5', 'col6'], 
    ['col7', 'col1', 'col5_alias' => 'col5', 'col2_alias' => 'col10']); 
} 
$timeFoo = microtime(true) - $timeFoo; 


$timeFoo2 = microtime(true); 
for($i = 0; $i < 1000000; $i++) { 
    foo2(
    ['col13', 'col5_alias' => 'col3', 'col8'], 
    ['col21', 'col5_alias' => 'col1', 'col9'], 
    ['col4', 'col5_alias' => 'col5', 'col6'], 
    ['col7', 'col1', 'col5_alias' => 'col5', 'col2_alias' => 'col10']); 
} 
$timeFoo2 = microtime(true) - $timeFoo2; 

echo "'foo' time: $timeFoo \n"; 
echo "'foo2' time: $timeFoo2 \n"; 

Ergebnisse unterscheiden sich von Zeit zu Zeit, aber nicht so viel:

'foo' time: 3.4310319423676 
'foo2' time: 2.5314350128174 

so gibt es uns fast 30% Leistungssteigerung.

Verwandte Themen