簡體   English   中英

PHP array_merge()首選數組和唯一值的首選項?

[英]PHP array_merge() with preference of first array and unique values only?

我想將多個數組合並在一起,同時優先考慮第一個數組中的值,並且只有唯一值。 有沒有比使用array_merge()array_unique()+運算符更快的方法?

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']);

只是合並數組會給我重復的值,並覆蓋第一個數組中的值:

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

使用array_unique()顯然可以修復重復值,但不能修復覆蓋的值:

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
)

實際上我沒有看到你的腳本有任何重大問題,我不知道你為什么要改進它。 但是我已經編寫了我的函數實現,看起來它運行得快一點,看看(我還添加了一些參數來測試函數結果):

<?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";

結果不時有所不同,但不是很多:

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

因此它為我們提供了近30%的性能提升。

你可以假設使用array_mergearray_unique函數和+運算符會很慢。 我寫了一些代碼來測試每種組合的速度......

這是代碼......

<?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 ();

這是輸出......

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

您可以看到每次添加函數調用時執行時間變長, array_mergearray_unique函數和+運算符最慢,速度超過兩倍。

但是,使用array_diff可以獲得正確的輸出,但沒有正確的排序。 向數組添加natsort函數調用可以解決這個問題。

例如...

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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM