0

I have the nested array ot transactions. One transaction has those elements 0=TransId, 1=ClientId, 2 = TransactionType, 4=Quantity:

$transactions = [
    [1,'CLIENT1','BUY',45.12],
    [7,'CLIENT2','BUY',25.15],
    [11,'CLIENT3','SELL',784.25],
    [14,'CLIENT1','SELL',7.04],
    [19,'CLIENT1','BUY',21.12],
    [21,'CLIENT2','SELL',14.12],
    [27,'CLIENT3','BUY',15.27]
];

I have another array, which represents Ids of VIP clients:

$vipClients = ['CLIENT2','CLIENT3'];

I am able to compute an array with transactions of VIP clients by means of foreach loop:

$vipTransactions = [];
foreach ($transactions as $transaction) {
    if (in_array($transaction[1], $vipClients)) {
        array_push($vipTransactions, $transaction);
    }
}
var_dump($vipTransactions);

I prefer to use php array functions instead of a foreach loop. Can you suggest me, how to filter nested array and value of nested segment, which will be filtered by existing value in other array? I want to use only array functions, not loops.

Armin66
  • 39
  • 1
  • 5
  • Have you looked into `array_filter()` at all? – Nigel Ren Oct 01 '22 at 09:48
  • It was my the first idea. But in callback function of `array_filter()` I need to work with 2 parameters: - 1st - element of `$transactions` array and - 2nd - array `$vipTransactions`. I don't know, how to pass 2nd parameter to callback function. – Armin66 Oct 01 '22 at 10:33
  • Half of the advice in the answer below is found [here](https://stackoverflow.com/a/10894463/2943403) from back in 2012. – mickmackusa Oct 17 '22 at 22:06

1 Answers1

1

You can use the use clause to pass the $vipClients array to the callback in array_filter to give you your desired result:

$vipTransactions = array_filter($transactions, function ($tx) use ($vipClients) {
  return in_array($tx[1], $vipClients);
});
var_dump($vipTransactions);

Alternatively (as @mickmackusa points out in the comments), if you use an arrow function (available since PHP7.4), you don't need the use clause:

$vipTransactions = array_filter($transactions,
                                fn($tx) => in_array($tx[1], $vipClients)
                                );

For both functions the output is:

array(4) {
  [1]=>
  array(4) {
    [0]=>
    int(7)
    [1]=>
    string(7) "CLIENT2"
    [2]=>
    string(3) "BUY"
    [3]=>
    float(25.15)
  }
  [2]=>
  array(4) {
    [0]=>
    int(11)
    [1]=>
    string(7) "CLIENT3"
    [2]=>
    string(4) "SELL"
    [3]=>
    float(784.25)
  }
  [5]=>
  array(4) {
    [0]=>
    int(21)
    [1]=>
    string(7) "CLIENT2"
    [2]=>
    string(4) "SELL"
    [3]=>
    float(14.12)
  }
  [6]=>
  array(4) {
    [0]=>
    int(27)
    [1]=>
    string(7) "CLIENT3"
    [2]=>
    string(3) "BUY"
    [3]=>
    float(15.27)
  }
}

Demo on 3v4l.org

Nick
  • 138,499
  • 22
  • 57
  • 95
  • Nice and works as required. But as a newbie I am rather confused about keyword `use($xy)`. I know the meaning - to pass other parameter to callback function. I have read the documentation here: [Anonymous functions](https://www.php.net/manual/en/functions.anonymous.php) and I am still confused. Can you provide me with some documents to help me better understand this keword of PHP. – Armin66 Oct 01 '22 at 14:18
  • @Armin66 I would suggest you google "php anonymous function"; there are many resources on the net which cover them and talk about `use`. For example: https://www.phptutorial.net/php-tutorial/php-anonymous-functions/ – Nick Oct 01 '22 at 21:34
  • `use` is not necessary with arrow function syntax. – mickmackusa Oct 17 '22 at 20:32
  • @mickmackusa indeed. I've made a note about that in the answer. – Nick Oct 17 '22 at 21:20