php按值从多维数组中删除重复项

时间:2021-04-19 04:45:32

I would like to remove duplicates by value as you can see from the list_title. I know there are several questions and answers to this but their solution doesn't work for me.

我想从list_title中看到,按值删除重复项。我知道有几个问题和答案,但他们的解决方案对我不起作用。

Here is what I've tried:

这是我尝试过的:

$uniqueArray = array_map("unserialize", array_unique(array_map("serialize", $notify)));

Result:

Array
(
[0] => Array
    (
        [list_id] => 86
        [list_reference] => 130948
        [list_title] => Offer:  apartment 2+kk 
        [list_city] => Prague
        [list_date] => 2017-03-03 11:20:35
        [list_status] => 0
        [list_creator] => Company A
        [list_price] => 30000
        [list_furniture] => ["1","0","0"]
        [list_accommodation] => flat
    )

[1] => Array
    (
        [list_id] => 87
        [list_reference] => 130947
        [list_title] => Offer:  apartment 2+kk 
        [list_date] => 2017-03-03 11:20:35
        [list_status] => 0
        [list_creator] => Company B
        [list_price] => 30000
        [list_furniture] => ["1","0","0"]
        [list_accommodation] => flat
    )

[2] => Array ...

Expected result should be one of those because of the title:

由于标题,预期结果应该是其中之一:

Array
(
[0] => Array
(
    [list_id] => 86
    [list_reference] => 130948
    [list_title] => Offer:  apartment 2+kk 
    [list_city] => Prague
    [list_date] => 2017-03-03 11:20:35
    [list_status] => 0
    [list_creator] => Company A
    [list_price] => 30000
    [list_furniture] => ["1","0","0"]
    [list_accommodation] => flat
)

4 个解决方案

#1


2  

Try this

<?php
    function super_unique($array)
    {
      $result = array_map("unserialize", array_unique(array_map("serialize", $array)));

      foreach ($result as $key => $value)
      {
        if ( is_array($value) )
        {
          $result[$key] = super_unique($value);
        }
      }

      return $result;
    }
    ?>

#2


1  

Thanks everyone, sometimes over-thinking can affect common sense.

谢谢大家,有时过度思考会影响常识。

I simply solved it from MYSQL query with something like:

我只是用MYSQL查询解决了它:

 GROUP BY list_title ORDER BY list_date

#3


1  

So basically you want to remove duplicates by 'list_title' column. Let's assume we keep the first occurrence of this title. Then you can use a couple of standard functions to achieve this:

所以基本上你想通过'list_title'列删除重复项。让我们假设我们保留了第一次出现这个标题。然后,您可以使用几个标准函数来实现此目的:

// Reverse array, so the first occurrence kept.
$data = array_reverse($data);

$result = array_reverse( // Reverse array to the initial order.
    array_values( // Get rid of string keys (make array indexed again).
        array_combine( // Create array taking keys from column and values from the base array.
            array_column($data, 'list_title'), 
            $data
        )
    )
);

Here is working demo.

这是工作演示。

UPDATE:

Based on @mickmackusa comment, the code can be simplified to:

根据@mickmackusa评论,代码可以简化为:

$result = array_reverse(array_values(array_column(
    array_reverse($data),
    null,
    'list_title'
)));

This is described in the docs regarding column_key parameter specs:

有关column_key参数规范的文档中对此进行了描述:

It may also be NULL to return complete arrays or objects (this is useful together with index_key to reindex the array).

返回完整的数组或对象也可能为NULL(这与index_key一起用于重新索引数组)。

#4


0  

Just loop through the arrays and keep track of duplicate field entries.

只需循环遍历数组并跟踪重复的字段条目。

Only the list_id and list_title will be considered for duplicate arrays but extra fields can be added. All the other keys are ignored.

对于重复数组,只考虑list_id和list_title,但可以添加额外的字段。所有其他键都被忽略。

<?php

$array = [
    [
        "list_id" => 86,
        "list_reference" => 130948,
        "list_title" => "Offer:  apartment 2+kk",
        "list_city" => "Prague",
        "list_date" => "2017-03-03 11:20:35",
        "list_status" => 0,
        "list_creator" => "Company A",
        "list_price" => 30000,
        "list_furniture" => '""1","0","0""',
        "list_accommodation" => "flat"
    ],
    [
        "list_id" => 87,
        "list_reference" => 130947,
        "list_title" => "Offer:  apartment 2+kk", 
        "list_date" => "2017-03-03 11:20:35",
        "list_status" => 0,
        "list_creator" => "Company B",
        "list_price" => 30000,
        "list_furniture" => '""1","0","0""',
        "list_accommodation" => "flat"
    ]
];


$duplicateFields = ["list_id" => array(), "list_title" => array()];
foreach ($array as $index => $value) {
    if(in_array($value['list_id'], $duplicateFields['list_id']) || in_array($value['list_title'], $duplicateFields['list_title'])){
        unset($array[$index]);
    }else{
        array_push($duplicateFields['list_id'], $value['list_id']);
        array_push($duplicateFields['list_title'], $value['list_title']);
    }
}

var_dump($array);

Which yields:

array(1) {
  [0]=>
  array(10) {
    ["list_id"]=>
    int(86)
    ["list_reference"]=>
    int(130948)
    ["list_title"]=>
    string(22) "Offer:  apartment 2+kk"
    ["list_city"]=>
    string(6) "Prague"
    ["list_date"]=>
    string(19) "2017-03-03 11:20:35"
    ["list_status"]=>
    int(0)
    ["list_creator"]=>
    string(9) "Company A"
    ["list_price"]=>
    int(30000)
    ["list_furniture"]=>
    string(13) """1","0","0"""
    ["list_accommodation"]=>
    string(4) "flat"
  }
}

#1


2  

Try this

<?php
    function super_unique($array)
    {
      $result = array_map("unserialize", array_unique(array_map("serialize", $array)));

      foreach ($result as $key => $value)
      {
        if ( is_array($value) )
        {
          $result[$key] = super_unique($value);
        }
      }

      return $result;
    }
    ?>

#2


1  

Thanks everyone, sometimes over-thinking can affect common sense.

谢谢大家,有时过度思考会影响常识。

I simply solved it from MYSQL query with something like:

我只是用MYSQL查询解决了它:

 GROUP BY list_title ORDER BY list_date

#3


1  

So basically you want to remove duplicates by 'list_title' column. Let's assume we keep the first occurrence of this title. Then you can use a couple of standard functions to achieve this:

所以基本上你想通过'list_title'列删除重复项。让我们假设我们保留了第一次出现这个标题。然后,您可以使用几个标准函数来实现此目的:

// Reverse array, so the first occurrence kept.
$data = array_reverse($data);

$result = array_reverse( // Reverse array to the initial order.
    array_values( // Get rid of string keys (make array indexed again).
        array_combine( // Create array taking keys from column and values from the base array.
            array_column($data, 'list_title'), 
            $data
        )
    )
);

Here is working demo.

这是工作演示。

UPDATE:

Based on @mickmackusa comment, the code can be simplified to:

根据@mickmackusa评论,代码可以简化为:

$result = array_reverse(array_values(array_column(
    array_reverse($data),
    null,
    'list_title'
)));

This is described in the docs regarding column_key parameter specs:

有关column_key参数规范的文档中对此进行了描述:

It may also be NULL to return complete arrays or objects (this is useful together with index_key to reindex the array).

返回完整的数组或对象也可能为NULL(这与index_key一起用于重新索引数组)。

#4


0  

Just loop through the arrays and keep track of duplicate field entries.

只需循环遍历数组并跟踪重复的字段条目。

Only the list_id and list_title will be considered for duplicate arrays but extra fields can be added. All the other keys are ignored.

对于重复数组,只考虑list_id和list_title,但可以添加额外的字段。所有其他键都被忽略。

<?php

$array = [
    [
        "list_id" => 86,
        "list_reference" => 130948,
        "list_title" => "Offer:  apartment 2+kk",
        "list_city" => "Prague",
        "list_date" => "2017-03-03 11:20:35",
        "list_status" => 0,
        "list_creator" => "Company A",
        "list_price" => 30000,
        "list_furniture" => '""1","0","0""',
        "list_accommodation" => "flat"
    ],
    [
        "list_id" => 87,
        "list_reference" => 130947,
        "list_title" => "Offer:  apartment 2+kk", 
        "list_date" => "2017-03-03 11:20:35",
        "list_status" => 0,
        "list_creator" => "Company B",
        "list_price" => 30000,
        "list_furniture" => '""1","0","0""',
        "list_accommodation" => "flat"
    ]
];


$duplicateFields = ["list_id" => array(), "list_title" => array()];
foreach ($array as $index => $value) {
    if(in_array($value['list_id'], $duplicateFields['list_id']) || in_array($value['list_title'], $duplicateFields['list_title'])){
        unset($array[$index]);
    }else{
        array_push($duplicateFields['list_id'], $value['list_id']);
        array_push($duplicateFields['list_title'], $value['list_title']);
    }
}

var_dump($array);

Which yields:

array(1) {
  [0]=>
  array(10) {
    ["list_id"]=>
    int(86)
    ["list_reference"]=>
    int(130948)
    ["list_title"]=>
    string(22) "Offer:  apartment 2+kk"
    ["list_city"]=>
    string(6) "Prague"
    ["list_date"]=>
    string(19) "2017-03-03 11:20:35"
    ["list_status"]=>
    int(0)
    ["list_creator"]=>
    string(9) "Company A"
    ["list_price"]=>
    int(30000)
    ["list_furniture"]=>
    string(13) """1","0","0"""
    ["list_accommodation"]=>
    string(4) "flat"
  }
}