12

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.

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
)
7
  • Is list_id unique? So you want to remove arrays with the same list_id? Commented Mar 3, 2017 at 11:08
  • @Shina But what are the unique fields? just list_id and list_title? Commented Mar 3, 2017 at 11:19
  • @iyop45 yes both should be unique. Thanks Commented Mar 3, 2017 at 11:22
  • so you want the array given below the the word "Result" to be converted the last array? Commented Mar 3, 2017 at 11:25
  • @marmeladze correct because that title is the same. I'm using array_unique($notify, SORT_REGULAR) which works fine but I think doesn't work on string values ... not sure. Commented Mar 3, 2017 at 11:27

3 Answers 3

13

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:

// 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:

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

This is described in the docs regarding column_key parameter specs:

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

Sign up to request clarification or add additional context in comments.

3 Comments

array_column() is smarter than this. Don't use array_combine(). See what happens when you set the 2nd parameter of array_column() to null.
Could someone explain to me how the updated solution works? I'm lost.
@YousofK. well, array_column will reindex array by list_title. That means that for the same list_titles the last item will override all previous. But we want the first item, not the last. So we use array_reverse to reverse an array in the beginning and reverse it back at the end.
5

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

I simply solved it from MYSQL query with something like:

 GROUP BY list_title ORDER BY list_date

Comments

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.

<?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 Comment

Making iterated in_array() calls is one of the most expensive ways to filter an array. This technique becomes proportionately unsavory as the size of the arrays increase. in_array() is a relatively slow technique because it cannot enjoy the performance benefits of searching by keys.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.