2011-10-18 10 views
6

多次元配列を別の配列でソートしようとしていますが、これまでのところ近づきません。
array_multisortは本当のソートのためだけに働いているようです。PHP - 別の配列で多次元配列をソート

$order = array(2,3,1); 

$data = array(
    array('id' => 1, 'title' => 'whatever'), 
    array('id' => 2, 'title' => 'whatever'), 
    array('id' => 3, 'title' => 'whatever') 
); 

今、私は私の$order配列の順序に従って、私の$data配列をソートしたいと思います:

は、私はこれらの2の配列があるとします。
これは私がする結果を希望するものである:

$data = array(
    array('id' => 2, 'title' => 'whatever'), 
    array('id' => 3, 'title' => 'whatever') 
    array('id' => 1, 'title' => 'whatever'), 
); 

私は、ネストされたループを実行することにより、容易にこれを達成することができますが、それは私の配列はかなり大きいです(うまくスケール、配列ではないでしょうより多くのフィールドを持っている)。

答えて

4

これはPHPのための組み込み関数はなく、私はusortを使ってこれを行うカスタム関数を考えることができません。しかし、array_mapは十分に単純です、imo、なぜ代わりに使用しないのですか?あなたの例では

$sorted = array_map(function($v) use ($data) { 
    return $data[$v - 1]; 
}, $order); 
+0

私の現在のバージョンのPHPで匿名の関数を使用することができません。 –

+0

ここに質問がありますhttp://stackoverflow.com/questions/13589707/php-modify-code-to-avoid-anonymous-functions –

0

usort()でカスタムソートを試すことができます。この方法で、最初の配列を使用して2番目の配列の順序を決定することができます。

+0

私はusortを見ていましたが、多次元配列で動作するかどうかはわかりません。 – MegaHit

+0

それがとても有用なものです。単なる文字列であろうと多次元配列であろうと、項目全体にアクセスできる関数を定義します。したがって、比較関数では、順序配列の各値インデックスを比較できます。このように何か:array_search($ a ['id']、$ order)> array_search($ b ['id']、$ order))? -1:1; –

4

は$ data配列内のIDを連続して1から始まる番号が付けられ、私は以下の与えるのコードは、これは常にそうであると想定されています。そうでない場合、コードは機能しません。

$result = array(); 
$index = 0; 
foreach ($order as $position) { 
    $result[$index] = $data[$position - 1]; 
    $index++; 
} 

http://codepad.org/YC8w0yHhには、あなたのサンプルデータで動作することがわかります。

EDIT

上記の仮定が成立しない場合は、次のコードは、同じ結果を達成する:

<?php 

$data = array(
    array('id' => 1, 'title' => 'whatever'), 
    array('id' => 2, 'title' => 'whatever'), 
    array('id' => 3, 'title' => 'whatever') 
); 

$order = array(2,3,1); 
$order = array_flip($order); 

function cmp($a, $b) 
{ 
    global $order; 

    $posA = $order[$a['id']]; 
    $posB = $order[$b['id']]; 

    if ($posA == $posB) { 
     return 0; 
    } 
    return ($posA < $posB) ? -1 : 1; 
} 

usort($data, 'cmp'); 

var_dump($data); 

は証明のためhttp://codepad.org/Q7EcTSfsを参照してください。

$ order配列でarray_flip()を呼び出すと、位置検索に使用できます。これは、ハッシュテーブルルックアップと似ています。ハッシュテーブルルックアップは、時間的に線形であり、O(n)です。あなたはより良くすることはできません。

+0

あなたの最後の解決策は、基本的には擬似入れ子ループを実行しています。それがうまくいくとは思わない。 – MegaHit

+0

@MegaHit私の答えで更新されたコードを参照してください、あなたはそれよりもうまくいくことはできません。 –

0

これは私がやる方法です。私は$ data配列と組み合わせてカスタムのusort関数(arr_sort)を使います。

<?php 
$order = array(2,3,1); 
$data = array(
    array('id' => 1, 'title' => 'whatever'), 
    array('id' => 2, 'title' => 'whatever'), 
    array('id' => 3, 'title' => 'whatever') 
); 
function arr_sort($a,$b){ 
    global $order; 
    foreach ($order as $key => $value) { 
    if ($value==$a['id']) { 
     return 0; 
     break; 
    } 
    if ($value==$b['id']) { 
     return 1; 
     break; 
    } 
    } 
} 
usort($data,'arr_sort'); 
echo "<pre>"; 
print_r($data); 
echo "<pre>";