1

I have the following array:

Array
(
    [0] => Array
        (
            [Import] => Array
                (
                    [product_id] => 1
                    [id] => 1
                    [category_id] => 1
                    [amount] => 50
                    [cost] => 8320
                    [paid] => 0
                    [comment] => transportation and others cost: 100  
                    [created] => 2015-06-22 12:09:20
                )

            [0] => Array
                (
                    [total_sell] => 6
                )

        )

    [1] => Array
        (
            [Import] => Array
                (
                    [product_id] => 2
                    [id] => 2
                    [category_id] => 2
                    [amount] => 15
                    [cost] => 3000
                    [paid] => 0
                    [comment] => 
                    [created] => 2015-06-22 12:10:36
                )

            [0] => Array
                (
                    [total_sell] => 1
                )

        )

    [2] => Array
        (
            [Import] => Array
                (
                    [product_id] => 1
                    [id] => 3
                    [category_id] => 1
                    [amount] => 15
                    [cost] => 2000
                    [paid] => 0
                    [comment] => 
                    [created] => 2015-06-22 12:10:58
                )

            [0] => Array
                (
                    [total_sell] => 6
                )

        )

    [3] => Array
        (
            [Import] => Array
                (
                    [product_id] => 1
                    [id] => 4
                    [category_id] => 1
                    [amount] => 50
                    [cost] => 8000
                    [paid] => 0
                    [comment] => 
                    [created] => 2015-06-23 01:10:10
                )

            [0] => Array
                (
                    [total_sell] => 6
                )

        )

)

I want to remove duplicate entry of [Import][product_id]. So my expected result is :

Array
(
    [0] => Array
        (
            [Import] => Array
                (
                    [product_id] => 1
                    [id] => 1
                    [category_id] => 1
                    [amount] => 50
                    [cost] => 8320
                    [paid] => 0
                    [comment] => transportation and others cost: 100  
                    [created] => 2015-06-22 12:09:20
                )

            [0] => Array
                (
                    [total_sell] => 6
                )

        )

    [1] => Array
        (
            [Import] => Array
                (
                    [product_id] => 2
                    [id] => 2
                    [category_id] => 2
                    [amount] => 15
                    [cost] => 3000
                    [paid] => 0
                    [comment] => 
                    [created] => 2015-06-22 12:10:36
                )

            [0] => Array
                (
                    [total_sell] => 1
                )

        )

)

Would you write a function to filter this type of array and produce expected result. I have been googling for 2 days but no luck.

3
  • 1
    php.net/manual/en/function.array-unique.php Commented Jun 23, 2015 at 23:35
  • When encountering semi-duplicates, which version of product_id do you want to keep in the final result? It looks like "first encountered". Is that right? Commented Jun 23, 2015 at 23:47
  • Yes. "first encountered" will be kept in final result Commented Jun 23, 2015 at 23:57

2 Answers 2

3

This is a handy one liner that should do the trick:

$unique= array_map("unserialize", array_unique(array_map("serialize", $original)));

If the underlying arrays are not identical, that won't work, in which case I think you could do:

$unique = array_intersect_key($original ,
              array_unique(
                  array_map(function($item) {
                      return $item['Import']['product_id'];
                  }, $original)
              )
           );

Tested: http://sandbox.onlinephpfunctions.com/code/8aee5cbd614e0ddd1a03dfaa7e98c72fbbe7d68d

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

4 Comments

Will this work if only the product_id's are the same, but other values are not the same? (I didn't downvote btw)
$unique= array_map("unserialize", array_unique(array_map("serialize", $old_array))); This does not work for me
We should ask the OP how he decides which version of product_id he wants to keep in the final result. It looks like "first encountered"
Yes. "first encountered" will be kept in final result
2

Here is a quick stable sort and reduce which runs in linearithmic time. First-encountered product Id's are kept, and entries with duplicate product Id's are ignored.

// Stable sort
sort($in);

// Reduce
$out = array_reduce($in, function(&$acc, &$item){ 
    if($item['Import']['product_id'] !== @$acc[sizeof($acc)-1]['Import']['product_id']) {
       $acc[] = $item;    
    }
    return $acc;
}, []);

Demo: http://ideone.com/BP0eUJ


Update: Here is an even better linear-time algorithm that does the same as above using a fast "hash table" lookup. Again, the first-encountered product Id is kept and subsequent ones of the same Id are ignored.

$out = []; 
$hashTable = [];
foreach($in as $item) {
  $pid = $item['Import']['product_id'];
  if(!isset($hashTable[$pid])) {
    $out[] = $item; 
    $hashTable[$pid] = true;
  }
}

Demo: http://ideone.com/5RF0og

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.