2

I have the following array dynamically generated from an external API:

$purchases = array(
    array('product_id' => 7, 'receipt' => R13D13),
    array('product_id' => 5, 'receipt' => Y28Z14),
    array('product_id' => 7, 'receipt' => R02310),
    array('product_id' => 5, 'receipt' => E11403)
);

Desired output:

$purchases_new = array(
    array('product_id' => 7, 'receipt' => R13D13),
    array('product_id' => 5, 'receipt' => Y28Z14)
);

Due to the nature of the API I have only been able to pull data using array_map:

$purchases_unique = array_unique(
    array_map(function($pid){ return $pid['product_id']; }, $purchases)
);
print_r($purchases_unique);

Outputs

array((array[251] => 7) array([252] => 5))

Output completely not what I want :( How to array_map 2 columns product_id' and receipt and remove duplicate rows based on product_id?

I want to achieve the following:

  1. array_map both columns? (product_id and receipt)
  2. Remove product_id duplicates rows based on product_id key?
Caconde
  • 4,177
  • 7
  • 35
  • 32
ianhman
  • 73
  • 1
  • 12
  • 2
    2) in your case why should those example win? – Goikiu Aug 13 '19 at 14:47
  • @Goikiu sorry I don't understand your question? If you are referring to the array_map code example I gave, it is an example. There is probably a much better solution which is why I posted here :) – ianhman Aug 13 '19 at 14:57
  • 2
    I didn't understand your rules to remove duplicated data. Why you are picking the first occurrence of `product_id` 7 (R13D13) and the second for `product_id` 5 (E11403)? – Caconde Aug 13 '19 at 15:08
  • @Caconde so basically each row is a product purchase order. As you will see 'product_id' 5 and 'product_id' 7 each have two occurrences. I only want to display one occurrence per product, otherwise the end user will see the same products twice. It does not matter if it's the first or last occurrence, it just needs to have unique products and show 'receipt' values. Hope that make sense. – ianhman Aug 13 '19 at 15:25
  • I have changed the desired output as the previous output was confusing people. – ianhman Aug 13 '19 at 15:32
  • @ianhman if you can have only the last unique id you can do it one-liner with `array_column` – dWinder Aug 14 '19 at 03:59

3 Answers3

1

I think this will do what you're looking for: Just adds the unique product_ids (with receipt) to a new array:

$purchases_new = array_reduce($purchases, function($acc, $p) {
    if(!in_array($p['product_id'], array_column($acc, 'product_id'))) {
        $acc[] = $p;
    }
    return $acc;
}, []);

Output:

array (
  0 => 
  array (
    'product_id' => 7,
    'receipt' => 'R13D13',
  ),
  1 => 
  array (
    'product_id' => 5,
    'receipt' => 'Y28Z14',
  ),
)

Try it online!

John
  • 577
  • 4
  • 20
1

As per the comment It does not matter if it's the first or last occurrence, you could use a foreach and create a $result array for the non duplicates.

For every iteration, use the product_id as the array key and check if it already has been set.

If it is not, then add it.

$purchases = array(
    array('product_id' => 7, 'receipt' => "R13D13"),
    array('product_id' => 5, 'receipt' => "Y28Z14"),
    array('product_id' => 7, 'receipt' => "R02310"),
    array('product_id' => 5, 'receipt' => "E11403")
);

$result = [];
foreach($purchases as $key => $purchase) {
    if (!isset($result[$purchase["product_id"]])) {
        $result[$purchase["product_id"]] = $purchase;
    }
}

print_r($result);

Result

Array
(
    [7] => Array
        (
            [product_id] => 7
            [receipt] => R13D13
        )

    [5] => Array
        (
            [product_id] => 5
            [receipt] => Y28Z14
        )

)

Php demo

The fourth bird
  • 154,723
  • 16
  • 55
  • 70
1

If you want the first occurrence use @TheFirstBird answer. If you want the last occurrence you can do it simpler buy using array_column and array_values as:

$newArr = array_values(array_column($purchases, null, "product_id")); 

Notice the second argument of array_column is null meaning take the entire element.

Live example: 3v4l

References: array-column, array-values

dWinder
  • 11,597
  • 3
  • 24
  • 39