2016-12-03 3 views
1

配列内の1レベルより深く表示される重複値に基づいて配列項目を削除します。アイテムが重複してソートされたら、新しい配列を並べ替えるのがいいでしょう。サブ配列の重複値に基づいて配列項目を削除し、次に配列を並べ替えます。

これは私がからすべての重複を削除したいと思います...

ARRAY 
(
    [0] => ARRAY 
    (
     [TYPE] => PHOTOS 
    ) 

    [1] => ARRAY 
    (
     [TYPE] => DOCUMENTS 
    ) 

    [2] => ARRAY 
    (
     [TYPE] => DOCUMENTS 
    ) 

    [3] => ARRAY 
    (
     [TYPE] => VIDEOS 
    ) 

    [4] => ARRAY 
    (
     [TYPE] => PHOTOS 
    ) 

) 

そしてI出力この配列からTYPEが、私はこれを取得する場合...

[TYPE] => PHOTOS 
[TYPE] => DOCUMENTS 
[TYPE] => DOCUMENTS 
[TYPE] => VIDEOS 
[TYPE] => PHOTOS 

現在の入力配列でありますこの入力が残っていますので、この新しい出力が残っています...

それぞれTYPE値に順序付けします。たとえば、変数や何かを使ってあらかじめ決められた注文を設定することができますか?新しい配列を特定の順序に並べ替えるためのアドバイス。この新しい順序を使用して...

$photos = 1; 
$videos = 2; 
$documents = 3; 

または多分配列を使用して、新しい秩序...

$new_order = array(
    1 => 'PHOTOS', 
    2 => 'VIDEOS', 
    3 => 'DOCUMENTS' 
) 

すべてのヘルプはとても良いでしょう。私はarray_uniqueとarray_mapを試しましたが、重複をチェックするサブ配列キーを指定する方法を見つけることができません。

これは私がこれまで試したものです...

$downloads = get_field('downloads'); 
$types = array_unique($downloads)); 

と私は配列を注文再限り取得できませんでした

$downloads = get_field('downloads'); 
$types = array_map("unserialize", array_unique(array_map("serialize", $downloads))); 

はあなたに「部分配列」重複を除去する

+0

私はわからないんだけど何を再あなたが言っている発注方法。しかし、 'array_unique'を使ってそれらの重複を削除することができます。 – Perumal

+0

'array_unique'は多次元配列では機能しません – RomanPerekhrest

+0

何かをクリアしてください。一意の型の配列または一意の型を持つ入力項目の配列のみを取得したいですか? – sevavietl

答えて

2

用いて、溶液array_columnarray_maparray_searchusort機能:カスタムオーダーの場合、私はusortを推奨

$new_order = array(
    0 => 'PHOTOS', 
    1 => 'VIDEOS', 
    2 => 'DOCUMENTS' 
); 

// $downloads is your input array 
$types = array_map(function ($v) { 
    return ['TYPE' => $v]; 
},array_unique(array_column($downloads, 'TYPE'))); 

usort($types, function($a, $b) use($new_order){ 
    $a_key = array_search($a['TYPE'], $new_order); 
    $b_key = array_search($b['TYPE'], $new_order); 

    if ($a_key == $b_key) return 0; 
    return ($a_key < $b_key)? -1 : 1; 
}); 

print_r($types); 

出力:

Array 
(
    [0] => Array 
     (
      [TYPE] => PHOTOS 
     ) 

    [1] => Array 
     (
      [TYPE] => VIDEOS 
     ) 

    [2] => Array 
     (
      [TYPE] => DOCUMENTS 
     ) 
) 
+0

私はここでこれをhttp://phpio.net/s/1lqlでテストしました。ありがとうございました。だから、あなたはより速く働くと思いますか?[あなたの答え](http://phpio.net/s/1lql)または[piotrの回答](http://phpio.net/s/1lpr)。 @ piotrの答えは、あなたのコードよりも少ないコードです。 – joshmoto

+0

@joshmoto、あなたは一つのことを忘れました - @ piotrの答えでは、結果の配列は初期配列に現れたので、 'TYPE'キーはありません – RomanPerekhrest

1

迅速かつ汚いソリューションをありがとう:

$a = []; 
$a[]['type'] = 'photos'; 
$a[]['type'] = 'documents'; 
$a[]['type'] = 'documents'; 
$a[]['type'] = 'videos'; 
$a[]['type'] = 'photos'; 


$b = []; 
foreach($a as $index => $subA) { 
    if(in_array($subA['type'], $b)) { 
     unset($a[$index]); 
    } else { 
     $b[] = $subA['type']; 
    } 
} 

ソートについて:ちょうどあなたがそれらを必要とするためにインデックスを設定し、重複を削除した後(ksortを使用します私があなたを正しく理解したと仮定して)。

+0

素早く汚れているかもしれませんが、重複したものはすべて削除します:-) http://phpio.net/s/1lpi時間をくれてありがとうございますが、私はgunaを@piotr cuaseに渡しています。しかし、ありがとう – joshmoto

0

array_reduceを使用してarray_uniqueを再実装することはできますが、外観の順に固有のタイプを収集することができます。これは後で配列をソートするのに役立ちます。

アレイを横断して、タイプキーが$typesに存在するかどうかをチェックします。存在する場合は、この要素をスキップします。それ以外の場合は、このキーを設定して$orderの値を割り当てます(ソートに使用されます)。

array_multisortを使用して、$uniqueDownloadsをソートすると、$typesがソートされます。

ここにはworking demoです。

anonymous functionsについてさらに読む。私は$types&と参照して渡しているので、元の配列の関数の値は変更されますが、コピーの値は変更されません。

+0

あなたの助けをありがとう、別の男が答えて、彼はあまりにも私が持っていると思う同じ配列wasntを使用しています。私は間違っているかもしれませんが、私は両方の解決策を使って生きている環境で今試してみます。しかし、ここで私の配列の入力で作業デモを更新しました。 http://sandbox.onlinephpfunctions.com/code/fee5fe1a10a3505803714bf4de82df7aa2482645ありがとう – joshmoto

+0

@joshmoto、 'TYPE'と' type'キーの問題です。あなたはケースを変更することができ、それは動作します。 – sevavietl

+0

私はあなたのバージョンで遊んだことがあります..同じ配列に基づいて私はhttp://phpio.net/s/1lq5を参照してください私は他の答えにfiddlesで使用した、私はおそらく間違い私は確信しています私はおそらくgunaは@ piotrに質問を与え、彼の機能は私が必要とするものを行う。あなたの時間をありがとう。 – joshmoto

1

2つの配列の共通部分を計算するarray_intersectを単に使用してください。 order arrayを最初の引数として使用すると、その配列が保持されます。

ご入力:

function do_awesomness($input, $key = 'TYPE', $order = ['PHOTOS', 'VIDEOS', 'DOCUMENTS']) 
{ 
    $result = []; 
    foreach($input as $k => $value) 
     $result[] = $value[$key]; 
    $result = array_unique($result); 

    return array_values(array_intersect($order, $result)); 
} 

使用法:

do_awesomness($input); 

の作業例:http://phpio.net/s/1lo1

+0

これは私にとって素晴らしいもののように見えますが、フィルタリングしようとしている実際の配列でphpio.netsで遊んでいて、エラーが発生しています。あなたのサンプル配列が1つのレベルの深さしかないからですか?私の多次元配列の入力を使って修正した作業例をご覧くださいhttp://phpio.net/s/1lpl – joshmoto

+0

すべてうまくいきます。 'TYPE'を' type'に変更し、 'Photos'、' Videos'、 'Documents'に値を並べ替えます。 – piotr

+0

これは一意の入力項目の配列ではなく、一意の型の配列だけを返します。また、 'foreach'を削除して[' array_column'](http://php.net/manual/en/function.array-column.php)を使うこともできます。 – sevavietl

0

$input = [ 
    ['TYPE' => 'PHOTOS'], 
    ['TYPE' => 'DOCUMENTS'], 
    ['TYPE' => 'DOCUMENTS'], 
    ['TYPE' => 'VIDEOS'], 
    ['TYPE' => 'PHOTOS'] 
]; 

私はあなたのニーズのすべてを達成するために、書き込み、単純な機能をしました

$array = [ 
    ['TYPE'=>'PHOTOS'], 
    ['TYPE'=>'DOCUMENTS'], 
    ['TYPE'=>'VIDEOS'] 
    ]; 

function customOrder($a, $b){ 
    $newOrder = [ 
     'PHOTOS' => 1, 
     'VIDEOS' => 2, 
     'DOCUMENTS' => 3 
    ]; 

    $valA = (array_key_exists($a['TYPE'],$newOrder))?$newOrder[$a['TYPE']]:999; 
    $valB = (array_key_exists($b['TYPE'],$newOrder))?$newOrder[$b['TYPE']]:999; 

    if($valA > $valB){ 
     $result = 1; 
    } elseif($valA < $valB){ 
     $result = -1; 
    } else { 
     $result = 0; 
    } 
    return $result; 
} 

usort($array, "customOrder"); 
var_dump($array); 
+0

あなたの時間のためにありがとう、私はすでに最高の@piotr答えをマークしましたが、私もあなたのグナをテストしています.. – joshmoto

+0

私はあなたのコードをここでテストしましたが、私の配列の入力... http://phpio.net/s/1lqfしかし、私は今働いている機能を持っている心配しないでください。多くのありがとう – joshmoto

+0

それはカスタム注文機能です。個人的には、最高の答えは@RomanPerekhrestのコードです。 –

関連する問題