2011-06-27 24 views
7

私は2つの配列を持っています。サブセット別にPHPの配列を配列

Array 
(
    [12] => blah 
    [36] => foo 
    [58] => blah 
    [60] => blah 
    [72] => blah 
    [90] => bar 
) 

他方が異なるために、異なるが関連するデータの小さなサブセットが各キーが大きいアレイ内の同じキーに対応すると、次のとおりです:

一つは、データのより大きなビットであります

Array 
(
    [36] => foo data 
    [90] => bar data 
    [12] => blah data 
) 

今、私の質問は、最初の配列をそのような順序にするにはどうすればよいのでしょうか?2番目の配列の対応するキーを持つ最初の配列のキーが最初に表示されます。 2番目の配列?

したがって、このように:

Array 
(
    [36] => foo 
    [90] => bar 
    [12] => blah 
    [58] => blah 
    [60] => blah 
    [72] => blah 
) 
+1

私は気にしませんが、ユーザー名は+1 ... –

+0

array_sortはあなたのために働くかもしれません – Colum

+0

おそらく['uksort'](http://php.net/manual/en/function.uksort.php )しかし私は考える閉鎖を使用せずに少し難しいです。どのPHPバージョンを使用していますか? –

答えて

1
$array1 = array(12 => 1, 36 => 2, 58 => 3, 60 => 4, 72 => 5); 
$array2 = array(36 => 1, 60 => 2, 12 => 1); 

# obtaining keys in the order of question  
$result = array_intersect_key($array2, $array1); 

# assign values from original $array1 
foreach($result as $key => &$value) { 
    $value = $array1[$key]; 
} 
unset($value); # kill reference for safety 

# add missing elements from $array1 
$result += $array1; 

var_dump($result); 

出力:

array(5) { 
    [36]=> 
    int(2) 
    [60]=> 
    int(4) 
    [12]=> 
    int(1) 
    [58]=> 
    int(3) 
    [72]=> 
    int(5) 
} 

は、アレイ用+ためArray Operatorsを参照してください。

2

使用uksort

編集:固定構文/ロジックエラーmalkoによって指摘。ありがとうございました。

$array_to_sort = array 
(
    12 => "blah", 
    36 => "foo", 
    58 => "blah", 
    60 => "blah", 
    72 => "blah", 
    90 => "bar" 
); 

$sorted_array = array(
    36 => "foo data", 
    90 => "bar data", 
    12 => "blah data" 
); 

global $sorted_array_keys; 
$sorted_array_keys = array_keys($sorted_array); 

function cmp($a, $b) 
{ 
    global $sorted_array_keys; 
    $a_in_array = in_array($a, $sorted_array_keys); 
    $b_in_array = in_array($b, $sorted_array_keys); 
    if ($a_in_array && $b_in_array) { 
     return array_search($a, $sorted_array_keys) - array_search($b, $sorted_array_keys); 
    } else if ($a_in_array) { 
     return -1; 
    } else { 
     return 1; 
    } 
} 

uksort ($array_to_sort , cmp); 
print_r($array_to_sort); 

これはきれいスタートを切ったが、かなり醜いと不明瞭なことになりました。私は今ではなく、他の答えのいくつかに傾いています。

+0

申し訳ありませんが、私の悪い投票(削除)はい可能性があります解決策が、詳細を与える必要があります。 – malko

+0

@malko - 私はちょうど尋ねられたことをするべきである例を掲示しました。 –

+0

@ jacobs、これがうまくいかない理由の1つは、関数cmpが$ keysをまったく知らないということです。 uksortの実例を見るには私の投稿を見てください( "closure"と "use"を使ってcompare関数に$ keysを知らせる) – malko

5

単純なO(n)溶液。

$arr1 = array(12 => 1, 36 => 2, 58 => 3, 60 => 4, 72 => 5); 
$arr2 = array(36 => 1, 60 => 2, 12 => 1); 

$result = array(); 

foreach($arr2 as $key => $value) { 
    $result[$key] = $arr1[$key]; 
    unset($arr1[$key]); 
} 

foreach($arr1 as $key => $value) { 
    $result[$key] = $arr1[$key]; 
} 

var_dump($result); 

出力:

array(5) { 
    [36]=> 
    int(2) 
    [60]=> 
    int(4) 
    [12]=> 
    int(1) 
    [58]=> 
    int(3) 
    [72]=> 
    int(5) 
} 
+0

ほぼ同じに投稿しようとしていました;) – malko

+0

+1時には物事は見た目より簡単です:) –

+0

必要はありません値を設定しないで、別のfor-each内のすべての重複項目をコピーする必要はありません。 – hakre

2

ここで閉鎖してuksort使用した例ですが、それは大きなアレイ上でより効果的でなければならない私は思うが、私は本当にに難しい...ので、任意のベンチマークを行っていませんw/oテストを確認します。

$a = array(
    12 => 'blah' 
    ,36 => 'foo' 
    ,58 => 'blah' 
    ,60 => 'blah' 
    ,72 => 'blah' 
    ,90 => 'bar' 
); 

$b = array(
    36 => 'foo data' 
    ,90 => 'bar data' 
    ,12 => 'blah data' 
); 

$keysPosition = array_flip(array_keys($b)); 
uksort($a,function($a,$b) use ($keysPosition){ 
    if(isset($keysPosition[$a],$keysPosition[$b])){ 
     return $keysPosition[$a]>$keysPosition[$b]?1:-1; 
    }else if(isset($keysPosition[$a])){ 
     return -1; 
    }else if(isset($keysPosition[$b])){ 
     return 1; 
    } 
    return 0; 
}); 

print_r($a); 

結果:

Array 
(
    [36] => foo 
    [90] => bar 
    [12] => blah 
    [72] => blah 
    [58] => blah 
    [60] => blah 
) 

あなたが閉鎖(PHP < 5.3)を使用することができない場合は、似たようなグローバルを使用して操作を行うことができますが、それがすべてできれいではありません。

+0

ありがとう!私の脳は今よりも痛い – herpyderpy