Php 根据子数组重复值删除数组项,然后重新排序数组

Php 根据子数组重复值删除数组项,然后重新排序数组,php,arrays,duplicates,Php,Arrays,Duplicates,基于在数组中更深一层显示的重复值删除数组项。一旦对重复项进行了排序,就可以重新排序新数组了 这是当前的输入数组 ARRAY ( [0] => ARRAY ( [TYPE] => PHOTOS ) [1] => ARRAY ( [TYPE] => DOCUMENTS ) [2] => ARRAY ( [TYPE] => DOCUMENTS ) [3] =&

基于在数组中更深一层显示的重复值删除数组项。一旦对重复项进行了排序,就可以重新排序新数组了

这是当前的输入数组

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

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

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

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

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

)
如果我从这个数组中输出
类型
,我会得到这个

[TYPE] => PHOTOS
[TYPE] => DOCUMENTS
[TYPE] => DOCUMENTS
[TYPE] => VIDEOS
[TYPE] => PHOTOS
我想删除此输入中的所有重复项,因此我将保留此新输出

[TYPE] => PHOTOS
[TYPE] => DOCUMENTS
[TYPE] => VIDEOS
但是是否可以对每个
类型
值进行设置和排序。例如,我可以使用变量或其他东西设置预定顺序。关于将新阵列重新排序为特定顺序的任何建议。使用此新订单

$photos = 1;
$videos = 2;
$documents = 3;
或者使用数组的新订单可能

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

任何帮助都会很好。我尝试了和数组映射,但似乎无法找到如何指定要检查重复项的子数组键

这就是我到目前为止所尝试的

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

我甚至没有重新订购阵列


感谢您为删除“子阵列”副本提供了快速而肮脏的解决方案:

$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(假设我理解正确)。

您可以使用重新实现,但按外观顺序收集唯一类型。这将有助于我们以后对数组进行排序

$order = [
    'PHOTOS' => 1,
    'VIDEOS' => 2,
    'DOCUMENTS' => 3    
];

$types = [];
$uniqueDownloads = array_reduce(
    $downloads,
    function ($uniqueDownloads, $download) use (&$types, $order) {
        $type = $download['TYPE'];

        if (!isset($types[$type])) {
            $types[$type] = isset($order[$type]) ? $order[$type] : 0;
            $uniqueDownloads[] = $download;   
        }

        return $uniqueDownloads;
    },
    []
);

array_multisort($types, $uniqueDownloads);
遍历数组时,我们检查类型键是否存在于
$types
中。如果存在,则跳过此元素。否则,设置此键并将
$order
中的值分配给它(这将用于排序)

然后,我们使用排序
$uniqueDownloads
$types
进行排序

这是

阅读更多关于。我通过引用
&
传递了
$types
,因此函数会更改原始数组的值,但不会更改副本的值。

只需使用它来计算两个数组的公共部分。若您使用order数组作为第一个参数,那个么它的顺序将被保留

你的意见:

$input = [
    ['TYPE' => 'PHOTOS'],
    ['TYPE' => 'DOCUMENTS'],
    ['TYPE' => 'DOCUMENTS'],
    ['TYPE' => 'VIDEOS'],
    ['TYPE' => 'PHOTOS']
];
我编写了一个简单的函数来满足您的所有需求:

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

工作示例:

对于我推荐的自定义订购
usort

$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);
$array=[
['TYPE'=>'PHOTOS'],
['TYPE'=>'DOCUMENTS'],
['TYPE'=>'VIDEOS']
];
功能自定义订单($a$b){
$newOrder=[
“照片”=>1张,
“视频”=>2,
“文档”=>3
];
$valA=(数组_键_存在($a['TYPE'],$newOrder))?$newOrder[$a['TYPE']]:999;
$valB=(数组_键_存在($b['TYPE'],$newOrder))?$newOrder[$b['TYPE']]:999;
如果($valA>$valB){
$result=1;
}elseif($valA<$valB){
$result=-1;
}否则{
$result=0;
}
返回$result;
}
usort($array,“customOrder”);
变量转储($数组);

使用
array\u column
array\u map
array\u search
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\u unique
删除这些重复项。
array\u unique
在多维数组上不起作用。请您清除一些内容。您想只获取唯一类型的数组还是具有唯一类型的输入项数组?这看起来确实很可怕,但我在phpio.net上玩了一个游戏,使用了我试图筛选的实际数组,它出现了一个错误。是不是因为示例数组只有一层深?请查看使用多维数组输入修改的工作示例,一切正常。只需将
类型
更改为
类型
,并将值排序为
照片
视频
文档
,这将只返回唯一类型的数组,而不是唯一输入项的数组。此外,您还可以删除foreach
并使用.No@joshmoto希望返回类型索引。我的函数允许他返回任何其他索引。实际上你是对的,我刚刚更新了区分大小写的值,它给了我完美的输出。谢谢@piotr为您提供的解决方案谢谢您的帮助,尽管另一个人回答了,他也使用了与我认为的阵列不同的阵列。尽管我可能错了,我现在将在我的生活环境中用这两种解决方案进行测试。但是我已经用我的数组输入更新了你的工作演示。thanks@joshmoto,出现
类型
类型
键的问题。你可以改变情况,它会起作用的。我已经玩过你的版本了。。请看fiddle,基于我在其他答案的fiddle中使用的相同数组,我肯定这可能是我犯的错误,但我可能是guna将问题交给@piotr,他的函数满足了我的需要。谢谢您的时间。@joshmoto,在小提琴中,添加
var_dump($uniqueDownloads)是有意义的以查看输出。快速和肮脏的可能,但它删除了所有的重复只是罚款:-)谢谢你的时间,但我是古纳给@piotr,因为他的功能是我所追求的。但是谢谢你的时间,我已经把@piotr answer标记为最好的,但是我也在测试你的。我在这里测试了你的代码,但是它似乎输出了我所有的数组输入。。。但别担心,我现在有了一个工作函数。许多thanksit的唯一定制订购功能。就个人而言,最好的答案是@RomanPerekhrest的代码。啊,我明白了,谢谢你。那么为什么[@RomanPerekhrest的]()代码比其他代码更好呢?它们都很好用,我不明白为什么哪一个更好?我刚刚在这里测试过,它也很好用。谢谢你抽出时间。那么,你认为哪一种工作更快,或者更有效@piotr的答案比你的少。@joshmoto,你忘了一件事-在@piotr的答案中,生成的数组没有
TYPE
键,就像它们出现在初始数组中一样
$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
        )
)