0

I'm using print_r(array_unique($array, SORT_REGULAR)); on the array below but it does not work.

I'm trying to filter out the redundant data.

Notice that [Order] and its key value pairs are all the same. But [Transaction] and its key value pairs are unique.

I need to get the [Order] element data and combine it with the 3 different [Transaction] elements.

My array

Array
(
    [0] => Array
        (
            [Order] => Array
                (
                    [PO] => TR11214
                    [OrderID] => 242856952012
                )

            [Transaction] => Array
                (
                    [TransPO] => TR11211
                    [TransactionPrice] => 91.17
                )

        )

    [1] => Array
        (
            [Order] => Array
                (
                    [PO] => TR11214
                    [OrderID] => 242856952012
                )

            [Transaction] => Array
                (
                    [TransPO] => TR11212
                    [TransactionPrice] => 180.41
                )

        )

    [2] => Array
        (
            [Order] => Array
                (
                    [PO] => TR11214
                    [OrderID] => 242856952012
                )

            [Transaction] => Array
                (
                    [TransPO] => TR11213
                    [TransactionPrice] => 209.99
                )

        )

)

The final array I need will look something like this.

Array
(
    [Order] => Array
        (
            [PO] => TR11214
            [OrderID] => 242856952012
        )

    [Transaction] => Array
        (
            [0] => Array
                (
                    [TransPO] => TR11211
                    [TransactionPrice] => 91.17
                )

            [1] => Array
                (
                    [TransPO] => TR11212
                    [TransactionPrice] => 180.41
                )

            [2] => Array
                (
                    [TransPO] => TR11213
                    [TransactionPrice] => 209.99
                )

        )

)

I can flatten the original array and then use array_unique, but wanted to see if there is a better way to accomplish what I need.

my code:

$myarray = array(
    0 => array(
    "Order" => array("PO" => "TR11214", "OrderID" => 242856952012),
    "Transaction" => array("TransPO" => "TR11211", "TransactionPrice" => 91.17)
    ),
    1 => array(
    "Order" => array("PO" => "TR11214", "OrderID" => 242856952012),
    "Transaction" => array("TransPO" => "TR11212", "TransactionPrice" => 180.41)
    ),
    2 => array(
    "Order" => array("PO" => "TR11214", "OrderID" => 242856952012),
    "Transaction" => array("TransPO" => "TR11213", "TransactionPrice" => 209.99)
    )
);


print_r(array_unique($myarray, SORT_REGULAR));
Mike
  • 607
  • 8
  • 30
  • 1
    you can use a foreach and transfer the contents to another container. use the necessary keys accordingly – Kevin Jan 23 '19 at 01:37
  • What if your input array has multiple *different* orders? – Nick Jan 23 '19 at 01:53
  • @Nick I'll set an if statement. the `Order` element will always have the same data in this if statement case. – Mike Jan 23 '19 at 01:55
  • But in that case why do you need `array_unique`? Or is that for the `if` condition? – Nick Jan 23 '19 at 02:03
  • @Nick the if statement would come before this scenario above. Meaning, the input array with multiple `Order` elements that are all the same, only happen in rare instances and my code would only execute to manipulate the array when these rare instances present themselves. I just need to get the array the way I need it in this rare case. – Mike Jan 23 '19 at 02:11
  • @Nick, I tried your answer before you deleted it and it does work. Just trying to edit it further to work better in my code. – Mike Jan 23 '19 at 02:57
  • @Mike I've updated and undeleted based on your comments to the answer – Nick Jan 23 '19 at 03:05

2 Answers2

1

array_unique() is intended for single dimensional arrays. If you want to use it on a multi-dimentional array, you should consider using usort() instead. Then you'll need to iterate through the array in reverse manually, searching for duplicates and removing them.

thefuzzy0ne
  • 479
  • 3
  • 10
1

If you want to determine how many unique values of the Order element there are in your array, you need to apply array_unique only to the Order elements, which you can do using array_column:

$unique_orders = count(array_unique(array_column($myarray, 'Order'), SORT_REGULAR));

You can process your array using a list of keys which have non-unique values to generate an array, while other keys will have just a single value:

$non_unique_keys = ['Transaction'];
$output = array();
foreach (array_keys($myarray[0]) as $key) {
    if (in_array($key, $non_unique_keys)) {
        $output[$key] = array_column($myarray, $key);
    }
    else {
        $output[$key] = $myarray[0][$key];
    }
}
print_r($output);

Example Output:

Array ( 
    [Order] => Array (
        [PO] => TR11214
        [OrderID] => 242856952012
    ) 
    [Sales Tax] => Array (
        [PO] => TR11214
        [SalesTaxAmount] => 0 
    )
    [Transaction] => Array (
        [0] => Array (
            [TransPO] => TR11211
            [TransactionPrice] => 91.17
        )
        [1] => Array (
            [TransPO] => TR11212
            [TransactionPrice] => 180.41
        )
        [2] => Array (
            [TransPO] => TR11213
            [TransactionPrice] => 209.99
        )
    )
)

Demo on 3v4l.org

Nick
  • 138,499
  • 22
  • 57
  • 95
  • Nick, what if another element is added to the input array? For example, another element after the `Order` element named `Salestax` like this, `[SalesTax] => Array ( [PO] => TR11214 [SalesTaxAmount] => 0.00)`. I have to manually enter the name of the element in your piece of code? I'm trying to make everything dynamic. – Mike Jan 23 '19 at 02:17
  • If it's a single unique element like `Order` you could add `'SalesTax' => $myarray[0]['SalesTax']` to the output array. Or if there are multiple values then `'SalesTax' => array_column($myarray, 'SalesTax')` – Nick Jan 23 '19 at 02:21
  • `Salestax` will be just like the `Order` element. It will be redundant data. There are other elements in the array besides `Order`, `Salestax` and `Transaction`. But all the elements data are redundant except for `Transaction` which is unique in each array. – Mike Jan 23 '19 at 02:25
  • very awesome. I had tried to do what you did with the `foreach` before you updated the answer, but could not quite get it. Your answer is spot on. This should work for other elements in the array that are like `Transaction` right? Just add the element key to the `non_unique_keys ` array? for example, there is an element named `Payment` and sometimes there are more than 1 payment per `Order`. In that case, I will need this code to do the same as what its doing for the `Transaction` element. – Mike Jan 23 '19 at 03:59
  • @Mike yes - for that case you would add `'Payment'` to the `$non_unique_keys` array. Note though that if you can get duplicated values in one of those columns (e.g. a case where there were a multiple payments but a different number of payments than transactions) you would need to use `array_unique` on the column. See my updated [demo](https://3v4l.org/otmid) - that shows a case with 2 payments and 3 transactions so a duplicated payment. – Nick Jan 23 '19 at 04:04
  • Got it. I will test it out with multiple `Payment` elements and leave another comment later. As always, thanks for your help. – Mike Jan 23 '19 at 04:11